Mais um blog inútil.

Drama

Agosto 3, 2018

Arvorezinha em Progress 4GL

Arquivado em: arvorezinha, coding, drama, fail, serious-business, useless, work — madinfo @ 16:35

Boa tarde,

Já não blolava á anos… resolvi blolar sobre uma linguagem que se chama Progress 4GL ou OpenEdge Advanced Business Language (OpenEdge ABL).
É uma linguagem linda que mais se devia chamar REGRESS em vez de Progress.

Aqui fica o código:

DEFINE VARIABLE i AS INTEGER NO-UNDO.
&SCOPED-DEFINE NumLoops  5    
DEFINE VARIABLE charz AS CHARACTER NO-UNDO INITIAL "*".

 REPEAT i = 1 TO {&NumLoops}:
     
     DISPLAY charz.
     charz = charz + "*".
END.


MESSAGE "Fim!!"
    VIEW-AS ALERT-BOX INFO BUTTONS OK.

Digam lá que não é a melhor coisa do mundo ?

Outubro 13, 2017

Novo Speedtester da NOS

Arquivado em: drama, fail, windows — falso @ 21:49

Ora viva,

Eu recentemente tenho tido vários problemas com as internets da NOS à noite, e isso tem me feito andar a fazer diversos telefonemas a reclamar e a ser sempre obrigado a correr o speedtester deles.

Até há poucos dias era uma cena normal.js que funcionava na maioria dos browsers, e uma applet JEWVA para o IE com extra faggotry. Mas agora decidiram INOVAR, e quando se inicia o teste, força o download de um .exe que supostamente tens que correr para fazer o speedtest, se não tiveres Windoze, azarito, não tens direito a te queixares com problemas de internets.

Bem, um .exe vindo da NOS não me parece uma boa ideia, então primeiro decidi enviar o executável para o virustotal para fazer scans, e o resultado foi:

Achei estranho como é normal, e ainda mais estranho eles não terem visto isto antes. Bora la então tentar ver o que isto faz. Vi que o executável era .NET portanto fui procurar um .NET decompiler, usei o ILSpy e vi o seguinte:

Achei que aquela string era um argumento para qualquer coisa Windoze based devido aos /qqcoisa, então googlando pela string achei este artigo, que explica que isto é usado para correr uma aplicação e apaga-la quando ela termina.

Passando para o MainForm, vi o seguinte:

Que mostra que tem outro executável embutido nele, extrai-o e executa, reparei também que no site da NOS, cada utilizador que faz download do speedtest, o ficheiro tem um nome diferente, chama-se “xperienceApp_XXXXXXXXXXXXXXXXXXXXX.exe” sendo o X diferente para cada utilizador ou cada IP da NOS que faz download do ficheiro, ainda não entendi bem isso, mas pelo que entendi esse ID é que depois é utilizado quando se faz o upload do resultado dos testes, portanto deve ser possível aldrabar isto :-P

Fui então tentar sacar os executaveis embutidos, e lembrei-me logo do binwalk, o resultado é o seguinte:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Microsoft executable, portable (PE)
...
507768        0x7BF78         Microsoft executable, portable (PE)
...
887308        0xD8A0C         Microsoft executable, portable (PE)
...

Mandei um binwalk -D ‘microsoft:exe’ xperienceApp_XXX.exe e passei ter mais dois executáveis gulosos. Então siga aprender a usar o radare2 só para dar numa de elite!

O primeiro executável, nas strings tem referencias ao curl, portanto faz requests para algum lado :-)

Depois fui cuscar o main, como vi antes, parece ir buscar um id, que pelos vistos é um ticket number ao NOME do executável, não ponho o dissassembly todo porque são mil linhas:

push str.xperienceApp       ; 0x457728 ; "xperienceApp"
...
push 0x457738               ; "_"
...
push 0x457740               ; ".exe"
...
push 0x456c68               ; "_"
...
push str.Ticket_Number:__s_n ; 0x456c6c ; "Ticket Number: %s\n"
...
push str.Wrong_Application_Name__Please_download_the_application_again__n ; 0x456c80 ; "Wrong Application Name (Please download the application again)\n"

Mais para baixo também tem umas strings gulosas:

push 0x456e50               ; "Kanguru.exe"
...
push 0x456e5c               ; "UIMain.exe"
...
push 0x456e68               ; "Optimus Kanguru.exe"
...
push 0x456e7c               ; "MphoneTools.exe"
...
push 0x456e8c               ; "AT+CIMI\r"
...
push 0x456edc               ; "AT+CGSN\r"
...
push str.IMEI               ; 0x456e98 ; "IMEI"
...
push str.Exception_when_try_to_open_COM_Port_n ; 0x456ee8 ; "Exception when try to open COM Port\n"

Diria que estão a procurar se esses executáveis estão a correr, que são clientes de modems 3G, e a ligar-se ao modem, a sacar a rede a que está ligada, o serial number e o IMEI, vai-se la entender porque é que o speedtest precisa disto tudo :-)

Mais para baixo, faz downloads em modo sequencial e paralelo via curl, e envia os dados para um servidor, por HTTP, porque HTTPS é coisa do futuro. E não tem mais nada.

Seguindo para o próximo, cuscando as strings, também usa o curl, porque raio é preciso outro programa?

string=\pcdiag_tempFile.txt
string=wmic os get freephysicalmemory
string=%s > %s%s
string=wmic os get caption
string= nicconfig where IPEnabled=True get Caption /format:table
string=netsh wlan show interfaces
string= PROCESS get name / Format:table
string=wmic /output:%s%s %s
string=netsh advfirewall show allprofiles state
string=wmic NIC where NetEnabled=true get Name, Speed | find "%s"
string=results_content: %s \n
string=PC Results Sended\n

( SENDED LOL)

Pelo que vi no dissassembly deste, tem as mesmas funcionalidades do anterior, mas tem uma parte EXTRA chamada “PC_Diagnostic” que cria um ficheiro temporário, e corre uma carrada de comandos do Windoze, manda o output para la, e provavelmente depois envia esse ficheiro para o servidor deles, novamente por http.

  • Vê a lista dos processos que estão a correr;
  • Corre o wmic para obter montes de informações do PC e dos interfaces de rede;
  • Apaga a KEY “ProxyBypass” no registry em HKCU\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\INTERNET SETTINGS\ZONEMAP e em “HKLM\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\INTERNET SETTINGS\ZONEMAP”;
  • Le o “HKLM\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\APP PATHS\CMD.EXE” que contem uma lista de apps instaladas;

Bem, para poder reclamar sem correr esta sida no meu PC, decidi sacar uma VM com o Windoze, e testar isto lá.

Pelos vistos analisar o executável no virustotal foi o que chegou para ficar blacklisted no Windoze Defender. Que LOLocausto. Então siga desactivar o Windoze Defender para poder correr isto numa VM para poder ligar para la a reclamar que tenho a net lixada…

Após estar ali um tempo a engonhar, a app saiu, o browser ficou à espera, e acabou por dar esse erro.

O pessoal que só usa Linux ou OSX deve também estar fascinado com esta mudança, não consigo entender como em 2017, onde existem mil ferramentas em JS pro browser, fds… o speedtest.net usa js e html5 e funciona bem, não entendo como pareceu bem na cabeça de alguém obrigar as pessoas a sacar um executável para correr.

Entendo que queiram sacar essas informações ao utilizador NORMIE para ajudar a diagnosticar problemas que possam não estar relacionados com o serviço deles, mas ao menos separavam isso numa ferramenta diferente, não punham isso no speedtest.
E também convinha fazerem isto de uma forma menos SHADY porque esconder executáveis dentro de outro executável é logo meio caminho andado para bater com os dentes no anti vírus.

Sinceramente agora nem sei o que fazer, porque nem consigo correr o speedtest para reclamar do serviço, portanto decidi vir blogar sobre isso.

Edit: Pelos vistos eles já adicionaram o tester antigo novamente ao site, portanto já não devo pelo menos ser obrigado a correr isto :-)

Edit2: Já rolaram cabeças em algum lado, e o teste já não está online, já voltou o antigo a ser o default.

Dezembro 26, 2011

Como não ganhar um iPad 2

Arquivado em: coding, cracking, drama, fail, useless — falso @ 03:09

Boas noites,

Venho hoje aqui blogar a minha tristeza ao saber que a password do concurso para ganhar um iPad 2 no Pplware é alta string manhosa.

Vou começar então a falar da minha jornada para tentar ganhar isto…

Comecei por andar a procurar qual era o software que usava a extensão “xcon”, um amigo meu descobriu entretanto que era o Conceal, um software todo manhoso em .NET.
Experimentei umas passwords básicas no programa só para ver se advinhava antes de fazer alguma coisa mais complexa, mas o programa era tão manhoso que se usasse uma password invalida ele crashava, então desisti dessa aproximação.

Falei com um amigo meu todo cromo da criptografia e ele automagicamente disse-me que aquilo eram blocos de TripleDES CBC.

Caso os senhores do Pplware não saibam, bruteforcar TripleDes não é assim pêra doce, citando a Wikipedia (está sempre correcta :-P):

“Deep Crack was designed by Cryptography Research, Inc., Advanced Wireless Technologies and the EFF. …  Advanced Wireless Technologies built 1856 custom ASICDES chips housed on 29 circuit boards of 64 chips each. The boards were then fitted in six cabinets and mounted in a Sun-4/470 chassis. … The entire machine was capable of testing over 90 billion keys per second. It would take about 9 days to test every possible key at that rate. On average, the correct key would be found in half that time.

Entretanto, eu sem sabendo que era alta string manhosa, e pensando que a password poderia ser o titulo de algum dos produtos entre 50 e 100€, fiz um scriptzinho que ia la parsar o site do OfficeLan e sacar de la os títulos todos (faz uso do phpQuery):

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<?php

require('phpQuery.php');

// batota, tem o total hardcoded
for($start = 0; $start <= 120; $start = $start + 20) {
	$url = 'http://shop.officelan.pt/pesquisa.html?start='.$start;
	$fields = array(
		'yagendoo_price_min'=>urlencode('50'),
		'yagendoo_price_max'=>urlencode('100'),
		'option'=>urlencode('com_yagendoo_vmsearch'),
	);
	$fields_string = "";
	foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
	rtrim($fields_string,'&');

	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

	$result = curl_exec($ch);

	curl_close($ch);

	$doc = phpQuery::newDocument($result);
	phpQuery::selectDocument($doc);

	foreach(pq('span.yagendoo_searchresult_title a') as $product) {
			echo $product->nodeValue;
			echo '<br/>';
	}
}

E com o resultado fui experimentar o seguinte:

<?php

$produtos = array(
  'MikroTik RouterBOARD 411U (Level 4) - RB411U - RB/411U',
  'MikroTik RouterBOARD 411AR (Level 4) - RB411AR - RB/411AR',
  ...
  'ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz Mimo',
  'ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz',
  'Presente', 'Presente_Natal', 'Presente_Natal.zip',
  'OfficeLan', 'pplware', 'natal',
);

$string = file_get_contents('nome_produto_offiLan.xcon');
foreach($produtos as $key) {
	$output = mcrypt_decrypt( MCRYPT_3DES , $key , $string , 'cbc');
	echo '<h4>'.$key.'</h4>';
	echo '<pre>'.$output.'</pre>';
}

Mas sem grandes resultados… Então foi que me disseram que o TripleDES CBC alem de uma key na cifra usa também outra variável, que é o IV (Initialization vector), que pelo que entendi, são dados usados para “inicializar” a cifra.
Então o tal programa tinha de usar algum algoritmo para “gerar” um IV a partir da nossa password ou então usava algum valor fixo, decidi tentar descobrir.

Andei a procura de técnicas sobre reversing a cenas .NET e achei alta programinha hacker, .NET Reflector.
Neste belo software, abre-se um executável .NET e ele escreve mais ou menos o codigo desse executável em belíssimo código C#, só os nomes de algumas funções e variáveis é que se perdem…

Então abri o executável do Conceal, e andei la a vasculhar, e no Form2 achei lá uma função chamada tdes_decrypt() e vi que era a função desejada, mas que a key e o IV eram calculados noutro lado, então com outra feature bonita deste programa, fiz Analyze nessa função e vi que era chamada pela func2(), e BINGO nessa achei o algoritmo que era usado para a key e o IV.

Decidi então criar um novo projecto C# no Visual Studio, onde iria utilizar o código do programa gerado pelo Reflector, mas podia-lhe alimentar um array gigante de passwords (a lista de produtos anterior). E com poucas dificuldades consegui mete-lo a funcionar, mas rapidamente vi que nenhuma das passwords que estava tentar usar era a correcta.
Sem saber mais o que tentar, rapidamente desisti…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace unconceal
{
    class Program
    {
        public static void tdes_decrypt(String inputfile, String outputfile, byte[] key, byte[] IV)
        {
            long bytecount = 0L;
            long fread_len = 0L;
            int numbytes = 0;
            byte[] mybuffer = new byte[0xf4241]; 
            TripleDESCryptoServiceProvider tdesProvider;
            CryptoStream cryptStream;

            FileStream freader = new FileStream(inputfile, FileMode.Open, FileAccess.ReadWrite);
            FileStream fwriter = new FileStream(outputfile, FileMode.OpenOrCreate, FileAccess.Write);

            fread_len = freader.Length;

            tdesProvider = new TripleDESCryptoServiceProvider();
            tdesProvider.Key = key;
            tdesProvider.IV = IV;
            tdesProvider.Padding = PaddingMode.Zeros;

            cryptStream = new CryptoStream(fwriter, tdesProvider.CreateDecryptor(), CryptoStreamMode.Write);
            int num = 0;
            num = inputfile.Length - 1;

            while (bytecount < fread_len)
            {
                numbytes = freader.Read(mybuffer, 0, 0xf4240);
                cryptStream.Write(mybuffer, 0, numbytes);
                bytecount += numbytes;
            }

            while (bytecount % 8 != 0)
            {
                cryptStream.WriteByte(0);
                bytecount++;
            }

            freader.Close();
            cryptStream.Close();
        }

        static void Main(string[] args)
        {
            List<string> passwords = new List<string>(new string[]
	        {
                "MikroTik RouterBOARD 411U (Level 4) - RB411U - RB/411U",
                "MikroTik RouterBOARD 411AR (Level 4) - RB411AR - RB/411AR",
                ...
                "ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz Mimo",
                "ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz",
                "Presente",
                "Presente_Natal",
                "Presente_Natal.zip",
                "OfficeLan",
                "pplware",
                "natal",
                "Natal",
                "iPad2",
                "Natal 2011",
                "PPLWARE.COM",
                "EBA428ECA16691133FA946FED56AF824E8527BB6",
                "_F2Liz12!" // password correct, mas só agora :(
        	});

            int x = 0;
            foreach (String for_keyf1 in passwords)
            {
                String password = for_keyf1.ToString();

                byte[] bytes = new byte[0x2710];
                int charIndex = 0;
                int length = for_keyf1.Length;
                byte[] buffer2 = new byte[length + 1];
                int index = 0;
                int num4 = 0;
                int num7 = length - 1;
                for (index = 0; index <= num7; index++)
                {
                    num4 += 3;
                    buffer2[index] = (byte)(Convert.ToInt64(for_keyf1[index]) + (index + num4));
                    num4--;
                }
                new ASCIIEncoding().GetBytes(Encoding.ASCII.GetString(buffer2), charIndex, Encoding.ASCII.GetString(buffer2).Length, bytes, charIndex);
                byte[] buffer3 = new SHA1CryptoServiceProvider().ComputeHash(bytes);

                byte[] key = new byte[24];
                key[0] = buffer3[2];
                key[1] = buffer3[6];
                key[2] = buffer3[0x12];
                key[3] = buffer3[0x10];
                key[4] = buffer3[0x13];
                key[5] = buffer3[1];
                key[6] = buffer3[9];
                key[7] = buffer3[7];
                key[8] = buffer3[14];
                key[9] = buffer3[3];
                key[10] = buffer3[8];
                key[11] = buffer3[0x11];
                key[12] = buffer3[10];
                key[13] = buffer3[15];
                key[14] = buffer3[0];
                key[15] = buffer3[11];
                key[0x10] = buffer3[9];
                key[0x11] = buffer3[4];
                key[0x12] = buffer3[0x12];
                key[0x13] = buffer3[5];
                key[20] = buffer3[11];
                key[0x15] = buffer3[2];
                key[0x16] = buffer3[0x13];
                key[0x17] = buffer3[0];

                byte[] iv = new byte[8];
                iv[0] = buffer3[2];
                iv[1] = buffer3[6];
                iv[2] = buffer3[0x12];
                iv[3] = buffer3[0x10];
                iv[4] = buffer3[0x13];
                iv[5] = buffer3[1];
                iv[6] = buffer3[9];
                iv[7] = buffer3[7];

                tdes_decrypt(@"C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\nome_produto_offiLan.xcon",
                    @"C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\" + x.ToString() + ".txt",
                    key, iv);

                string text = System.IO.File.ReadAllText(@"C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\" + x.ToString() + ".txt");
                System.Console.WriteLine("String = {0}", text);
                x++;
            }
        }
    }
}

Hoje dia 26 de Dezembro, lembrei-me de ir ver qual era afinal a password do concurso, e foi então que descobri que era “_F2Liz12!”, adicionei essa string ao meu programinha em C# e não é que funcionou?

Download do projecto unconceal (belo nome :-P) para Visual Studio, para caso alguém esteja interessado em brincar mais com isto. Não esquecer os caminhos que estão hardcoded ao chamar a função tdes_decrypt().

Acho que para a próxima os senhores do Pplware deviam fazer concursos mais bem pensados, onde ganhe quem acha o resultado final, e não quem escolhe um produto à sorte que esteja no intervalo de preços dito inicialmente (dor de corno).

Um abraço e até à próxima!

Dezembro 14, 2010

Árvorezinha 2.0

Arquivado em: arvorezinha, assembly, coding, drama, useless — falso @ 01:07

Ora viva amigos!

Há uns tempos no trabalho um colega meu começou a fazer pouco das minhas árvorezinhas, a dizer que só eram meia árvore, e que eu devia era de fazer uma árvore completa. Eu fiquei SENTIDO com tal AFRONTA, e fiquei a MATUTAR sobre isso, até que decidi por mãos à obra, e criar a Árvorezinha 2.0.

Primeiro decidi faze-la em C porque é a linguagem STANDARD!

[sourcecode language="c"]
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        int altura;
        int i,x;
        int lul;

        if (argc < 2)
        {
                return(0);
        }
        altura = atoi(argv[1]);

        /* Ciclo da altura da Arvore */
        for(i = 1; i <= altura; i++)
        {

                /*
                        Numero de Espaços
                        Começa em 0 porque existem linhas com 0 espaços
                        Algoritmo: altura - linha
                */
                for(x = 0 ; x < (altura-i); x++)
                {
                        putchar(' ');
                }

                /*
                        Numero de Asteriscos
                        Começa em 1 porque não existem linhas sem *
                        Algoritmo: (2 * linha) - 1
                */
                for (x = 1; x <= (2*i)-1; x++)
                {
                        putchar('*');
                }

                putchar('\n');
        }

        /* Largura ultima linha */
        lul = (altura * 2) - 1;

        /*
                Ciclo da altura do tronco
                Algoritmo: altura / 2
        */
        for(i = 1; i <= (altura/2); i++)
        {
                /*
                        Por causa do ASCII nao permitir meio char
                        tive de fazer duas implementacoes diferentes,
                        uma para quando o  valor da altura do tronco
                        e' par, e outra para quando e' impar.
                */
                if (altura % 2)
                {
                        /* Impar */

                        /*
                                Numero de Espaços
                                Algoritmo: (lul / 4) - 1
                        */
                        for(x = 0; x <= (lul/4)-1; x++)
                        {
                                putchar(' ');
                        }


                        /*
                                Numero de # (tronco)
                                Algoritmo: lul / 2
                        */
                        for(x = 0; x <= (lul/2); x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
                else
                {
                        /* Par */

                        /*
                                Numero de Espaços
                                Algoritmo: lul / 4
                        */
                        for(x = 0; x <= (lul/4); x++)
                        {
                                putchar(' ');
                        }


                        /*
                                Numero de # (tronco)
                                Algoritmo: (lul / 2) - 1
                        */
                        for(x = 0; x <= (lul/2)-1; x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
        }

}

[/sourcecode]

A pedido de muitas famílias, foi me imposta a tarefa de fazer um RFC da nova árvorezinha, mas não tenho muito jeito para escrever algoritmos em pseudo-código. Então tal obra heróica fica para o caro leitor, façam me um baseado no código em C e enviem-me!

Segundo as próprias leis já pré-estabelecidas da Árvorezinha, tem de existir uma implementação em Assembly! Então não podia cá faltar a minha versão em x86 Assembly.

[sourcecode language="plain"]

;
; Arvorezinha 2.0
; x86 Assembly
; Copyright (C) 2010 Pedro de Oliveira
; //blol.org
;
; this assembly can never fail
;
        BITS            32
        GLOBAL          main

; Vou usar duas funcoes da libc para o codigo nao crescer gigantescamente
; com rotinas que nao interessam nada para aqui.
        EXTERN          atoi
        EXTERN          printf

; Definicao das Variaveis
SECTION         .data

        argc    dd      0
        argv    dd      0

        erro    db      "ERRO! Executar: %s <altura da arvore>",10,0

        card    db      '#'
        newl    db      0xa
        aste    db      '*'
        espa    db      ' '

        altura  dd      0
        i       dd      1
        x       dd      0
        lul     dd      0

; He cometh!
SECTION         .text

main:
        pop     eax                     ; Ignorar...

        pop     eax                     ; Saca o argc da Stack
        mov     dword [argc], eax       ; Guarda o valor na variavel argc

        pop     ebx                     ; Saca a posicao de memoria do
                                        ; argv[0] da Stack
        mov     eax, dword [ebx]        ; Mete a posicao em EAX
        mov     [argv], eax             ; Guarda-a em argv

        add     ebx,0x4                 ; Salta 4 bytes para a frente
                                        ; para o argv[1] ficar em EBX

        mov     eax, [argc]             ; Mete o argc em EAX
        cmp     eax, 0x2                ; Verifica se e' diferente de 2
        jne     jafoste                 ; Se for sai com erro

        push    dword [ebx]             ; Mete o valor de argv[1] na Stack
        call    atoi                    ; Corre o atoi com esse valor
        mov     [altura], eax           ; O resultado fica em EAX, guarda
                                        ; na variavel altura

ciclo_linhas:
        ; INICIO - CICLO DAS LINHAS DA ARVORE
        mov     eax, [i]                ; i em EAX
        mov     ebx, [altura]           ; altura em EBX

        cmp     ebx, eax                ; Compara
        jb      prepara_tronco          ; i > altura ? proximo passo
        mov     dword [x], 0            ; Mete x a 0

ciclo_espacos:
        ; INICIO - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS
        mov     eax, [x]                ; x em EAX

        ; pretende-se (altura - i) em EBX
        mov     ebx, [altura]           ; altura em EBX
        mov     ecx, [i]                ; i em ECX
        sub     ebx, ecx                ; EBX - ECX

        cmp     ebx, eax                ; Compara
        jbe     prepara_asteriscos      ; x >= (altura - i) ? proximo passo

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_espacos           ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS

prepara_asteriscos:
        mov     dword [x], 1            ; Mete x a 1

ciclo_asteriscos:
        ; INICIO - CICLO DE ASTERISCOS (ARVORE)
        mov     ebx, [x]                ; x em EBX

        ; pretende-se (2 * i) - 1 em EAX
        mov     eax, 2                  ; 2 em EAX
        mov     ecx, [i]                ; i em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX

        cmp     eax, ebx                ; Compara
        jb      fim_ciclo_linhas        ; x > (2*i)-1 ? proximo passo

        push    aste                    ; Asterisco
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_asteriscos        ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ASTERISCOS (ARVORE)

fim_ciclo_linhas:
        push    newl                    ; Newline
        call    print                   ; write()

        call    incrementa_i
        jmp     ciclo_linhas            ; Volta para o inicio
        ; FIM - CICLO DAS LINHAS DA ARVORE

prepara_tronco:
        ; pretende-se (altura * 2) - 1 em EAX
        mov     eax, [altura]           ; altura em EAX
        mov     ecx, 2                  ; 2 em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX
        mov     dword [lul], eax        ; Guarda a largura da ultima linha
                                        ; em lul


        mov     dword [i], 1            ; Mete o i a 1

ciclo_linhas_tronco:
        ; BEGIN - CICLO DAS LINHAS DO TRONCO
        mov     ecx, [i]                ; i em ECX

        ; pretende-se (altura / 2)
        mov     eax, [altura]           ; altura em EAX
        shr     eax, 1                  ; divide por 2

        cmp     ecx, eax                ; Compara ECX com EAX
        jg      sair                    ; i > (altura / 2) ? Adeus!

        mov     eax, [altura]           ; altura em EAX
        test    eax, 1
        je      pc_tronco_par_espacos   ; e' par?

; --------------------------- IMPAR -------------------------------
pc_tronco_impar_espacos:
        mov     dword [x], 0            ; Mete-se x a 0

c_tronco_impar_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em EAX

        ; pretende-se (lul / 4) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; Divide por 4
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_impar_cardinal; x > (lul/4)-1 ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_impar_espacos  ; Volta para o inicio
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)

pc_tronco_impar_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_impar_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x > (lul/2) ? Next!

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_impar_cardinal ; Volta para o inico
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (IMPAR)

; --------------------- FIM IMPAR --------------------------------


; ----------------------------- PAR ------------------------------
pc_tronco_par_espacos:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 4) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; divide por 4

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_par_cardinal  ; x > (lul / 4) ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_par_espacos    ; Volto para o inico do ciclo
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)

pc_tronco_par_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x > (lul / 2) - 1 ? uhuhuh

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_par_cardinal   ; Volta para o inicio do ciclo
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (PAR)
; ----------------------- FIM PAR ----------------------------------

fim_ciclo_linhas_tronco:
        push    newl
        call    print

        call    incrementa_i
        jmp     ciclo_linhas_tronco     ; Volta para o inico do ciclo
        ; FIM - CICLO DAS LINHAS DO TRONCO

jafoste:
        mov     eax, [argv]             ; Mete o apontador de argv em EAX
        push    dword eax               ; Mete o endereço de argv na Stack
        push    dword erro              ; Mete o endereço da String na Stack
        call    printf                  ; Escreve no ecra!


sair:
        mov     ebx,0x0                 ; valor de saida
        mov     eax,0x1                 ; sys_exit
        int     0x80

print:
        mov     ecx,[esp+4]             ; Mete o argumento em ECX
        mov     edx,1                   ; Length
        mov     ebx,1                   ; stdout
        mov     eax,4                   ; sys_write
        int     0x80
        ret

incrementa_x:
        mov     eax, [x]
        inc     eax
        mov     dword [x], eax
        ret

incrementa_i:
        mov     eax, [i]
        inc     eax
        mov     dword [i], eax
        ret
[/sourcecode]

E aqui vai a prova dos nove:

[sourcecode language="plain"]
falso@lemonparty:~/src/zbr$ make
rm -f arvore2 arvore.o
nasm -f elf arvore.asm -o arvore.o
gcc -g -o arvore2 arvore.o
falso@lemonparty:~/src/zbr$ ./arvore2 4
   *
  ***
 *****
*******
  ###
  ###
falso@lemonparty:~/src/zbr$ ./arvore2 5
    *
   ***
  *****
 *******
*********
  #####
  #####
falso@lemonparty:~/src/zbr$
[/sourcecode]

Espero lançar futuramente um género de Unit Tests, para testar as varias implementações da Arvorezinha 2.0 que possam surgir, para ver se cumprem o standard ou não.

Espero que tenham gostado do post, até à proxima, fiquem bem e joguem muito! Chuuuuuuack!

Outubro 28, 2010

Scam nos leilões do ClubeFashion

Arquivado em: drama, fail, serious-business, useless — falso @ 09:32

Ora viva amigos!

Hoje não venho aqui blogar de nada relativo a Informáticas, mas sim a um scam lindo que achei nas Internets portuguesas.

Então estava eu ontem muito bem no meu covil, a fazer a lida das coisas inúteis do dia-a-dia, quando a minha FC se vira para mim e diz-me que o site ClubeFashion (que já é conhecido por dar altas baldas de 1 e 2 meses para entregar as coisas que se compra la) agora tem leilões, e que haviam la pessoas a ganhar coisas mirabolantes por preços bues baratos.

Eu achei que isso cheirava a esturro, porque em Portugal, ninguém da nada a ninguém. Então decidi investigar melhor a coisa.

Então funciona desta maneira, para se licitar em algo, tem de se fazer um carregamento de “Bids” do site. 10 Bids = 5€, 20 Bids = 10€, etc.
Então basicamente sempre que se faz uma licitação, mesmo que não se ganhe, ou se alguém der um valor superior eles ganham logo 0.50€. Até aqui está MAIS ou MENOS bem, até que se entra na pagina de um leilão a decorrer actualmente…

Agora aqui é que parte a loiça toda. Pelos vistos (já tinha visto ontem à noite) os leilões arrancam sempre com o valor inicial de 1€. E depois temos a seguinte informação:

\* A sua licitação subirá o valor em 0.01€.
\* Abaixo de 2 MINUTOS, qualquer licitação reinicia o contador.

Então isto funciona mais ou menos assim, eles têm uma coisa para leiloar, mas com o dinheiro que vão ganhar com as licitações, vai chegar para pagar o que quer que estejam a leiloar, e ainda um lucro de mais de 100%. E claro que se o leilão estiver a acabar, sem terem sido feitas licitações suficientes, eles têm um script que faz automaticamente licitações com fake accounts, para o tempo nunca terminar até fazerem o dinheiro suficiente.

Vamos ver então um exemplo, a “Viagem Lufthansa para a Europa”, dizem que o PVP Loja é 358€ e quem ganhou o leilão, ganhou por 79.90€.
Então o leilão começa a 1€. 79.90€-1€ da 78.90, que dá 7890 licitações, então vamos ver, 7890 * 0.50€ = 3945€, então eles com este leilão da viagem que custava 358€ ganharam 3587€, está um belo negocio hein?

Bem, eu achei isto tanta roubalheira, que necessitei de vir blogar sobre isto, espero que gostem! E leiam tudo bem antes de serem enganados por estes sites malandros. Até à proxima, fiquem bem e joguem muito.

Setembro 1, 2010

Bus Pirate - Firmware update

Arquivado em: drama, fail, useless — thread @ 23:04

Bom noite amiguinhos!! (disseram-me que “amiguinhos” ficava muito gay, então decidi editar).

Estive quase para blogar sobre a aventura que foi conseguir recuperar a password neste blog inútil… mas fica para outra vez.

Ora estava eu hoje com vontade de arranjar problemas e decidi fazer um firmware update ao meu Bus Pirate. Dei uma vista de olhos na diagonal no site mas como não estava com muita paciencia para ler, decidi logo zergar à campeão e fiz logo o download do maior numero que sufixava o nome dos ficheiros de firmware disponiveis para download no repositório.

Mal aquilo acabou de sacar a coisa, liguei-me via serie ao Bus Pirate, activei o bootloader mode, e em seguida fiz logo cócó:

Pronto… depois de rapidamente perceber que tinha brickado o Bus Pirate, também percebi que esta coisa ia tentar rescrever o bootloader que por sua vez estava activo.. e não ia poder ser re-escrito!

Agora sim, tinha um desafio e uma vontade enorme de fazer serão à volta disto para o unbrickar.
E decidi também blogar sobre isto caso alguem faça o mesmo cócó que eu fiz… pode ser que seja uma coisa pouco útil dentro desta vasta inutiilidade que estão para ver!

Comecei pelo que pensei ser o caminho mais simples… dado que o Bus Pirate tem uma interface ICSP, decidi tentar aceder directamente à pic com o auxilio dum pic debugger/programmer.

Portanto peguei então no lixo seguinte:

Montei o estaminé seguinte:

Alimentado pela besta seguinte:

Ora resumindo pseudo-tecnicamente a coisa, fiz o seguinte:
Interliguei o pickit3 ao interface ICSP do bus pirate com os cabinhos e alimentado por uma fonte de alimentação… (que podia ser 2 pilhas ou usar o próprio pickit3.. mas achei que assim ficava mais giro e tenho de dar uso as inutilidades cá de casa!) E as relações de cor/função na foto são:

amarelo -> MCLR | vermelho -> 3.3V | preto -> ground | azul -> PGD | verde -> PGC

Após esta cangalhada estar bem ligada, deve acender um led vermelhinho e outro verde no bus pirate. Se não acender e se eventualmente cheirar a queimado significa que têm de encomendar umas coisinhas na farnell ou assim.
Dado isto, está na altura de aproveitar o que o opensource tem de bom, e descarregar uma versão qualquer das sources do bus pirate para a sua amada pic. Decidi descarregar primeiro as sources da versão 4.3 e abri no mplab. (Nota… se realmente estiverem a salvar um bus pirate e queiram poupar tempo e trabalho… passem já para a parte final do post onde tem uns procedimentos de 1 a 15, que indica como flashar um bootloader e firmware com hex files, poupando assim a trabalhera de compilar as coisas todas.)

Algo importante a referir aqui, é que caso estejam a fazer este procedimento, devem instalar o mplab juntamente com outro pacote da microchip -> O mplab c30 (pode ser a versão LITE) que contem o toolkit para compilar e linkar os projects para pic24’s (que vêm no bus pirate v3).

Caso tudo esteja correcto, indo a Project -> Build all deverão obter o resultado seguinte:

Agora só se tem que selecionar o programador que vai ser usado para escrever o firmware.. que neste caso é um pickit3: Programmer -> Select Programmer -> 4 Pickit3.

E selecionar o pic em questão… que no caso do meu bus pirate v3 é o PIC24FJ64GA002 (mais alguem que esteja a fazer isto, deverá conferir a sopa de letras na pic do seu bus pirate e selecionar a correspondente): Configure -> Select Device -> Device:

Com isto, penso que é seguro dizer que se pode ir a Programmer -> Program, que deverá dar o seguinte resultado:

Agora só têm que desligar a fonte de alimentação, desligar o pickit3, retirar os cabinhos todos do interface ICSP, ligar por usb ao pc, e abrir um terminal na COMx correspondente e ver se o gajo respira:

E parece que sim! De novo à vida inútil, pronto para ir para a prateleira mais uns meses apanhar pó…

Agora já só falta colocar um bootloader nisto, que como podem ver está com a v255.255 que quer dizer isso mesmo que estão a pensar.

Para poupar espaço no blog, vou apenas referir os procedimentos sem estar a largar mais screenshots.

1 - ligar novamente o bus pirate ao pickit3 com os passinhos todos anteriores.
2 - abrir o mplab
3 - ir a File -> Import -> selecionar o .hex file que contem o bootloader desejado. No meu caso: BPv3-Bootloader-v4.4.hex
4 - Selecionar o programador em Programmer -> Select Programmer e selecionar o device em Configure -> Select Device
5 - ir a Programmer -> Program
6 - se não houver erros, desligar o bus pirate do pickit3 e da alimentação (verificar que o bus pirate está mesmo desligado)
7 - short entre PDC e PGD (basicamente, ligar o cabo azul ao verde)
8 - Ligar o bus pirate por usb
9 - tentar pingar o bootloader com: pirate-loader.exe –dev=COM3 –hello
10 - Se não houver erros até aqui, estamos prontos para colocar novamente um firmware, neste caso será o último, o 5.7
11 - Abrir o ds30 Loader GUI.exe (esta util bem como o pirate-loader encontram-se no pacote de update de firmware/bootloader que se pode descarregar do repositorio de code do bus pirate).
12 - Selecionar o BPv3-Firmware-v5.7.hex e pressionar “Download” (claro está que se quiserem uma versão custom da coisa, têm que sacar a source, compilar, etc.. basicamente seguir os passos descritos anteriormente neste post).
13 - Se não houver erros, desligar o bus pirate do usb
14 - retirar o short entre o PDC e PGD (melhor ainda -> desligar todos os cabos… já não vão ser necessários)
15 - Ligar o bus pirate por usb novamente e aceder à consola pela respectiva COMx

Deverão ter o seguinte aspecto:

E pronto…

Agora que já vos gastei 5 ou 10 minutos do vosso tempo, já posso ir jogar Starcraft II.

Maio 29, 2010

Portugal@Rippar - Os rippers contra-atacam

Arquivado em: arvorezinha, drama, java, serious-business — falco @ 10:51

Antes de mais, devo dizer, que estou emocionado pela quantidade de arvorezinhas que surgiram depois dos meus dois posts de arvorezinhas…

Agora vou ao assunto deste post.
O “ripanço” (desculpa dcoder), no Portugal@Rippar está de volta!
Digo de volta porque até uma arvorezinha já foi ripada. Um dia conto o drama todo como deve ser, mas vai ser difícil porque eu não ripei o texto da discussão antes dos donos do fórum o terem apagado para esconder as asneiras que fizeram e as acusações injuriosas que fizeram a mim e ao falso.

Desta vez algum “ripper” resolveu rippar uma calendário feito em java o jcalendar. O GNU Cop, já avisou os moderadores do fórum, vamos ver agora como vai decorrer o drama.

Update: O autor do software já corrigiu a situação.

Fevereiro 1, 2010

Falando em vampiros...

Arquivado em: drama, fail, useless — madinfo @ 23:20

Pois bem amigalhaços já que o tema dos vampiros veio ah baila também eu tenho que blogar sobre o assunto…

Eis que surge na TVI uma coisa inédita… uma novela sobre vampiros (coisa nunca vista) cujo nome é: “Destino Imortal” passada na Serra de Sintra, com um amor impossível entre um rapaz e uma rapariga (querem saber mais vejam a novela…).

A SIC sem mais demoras (não copiando nada) faz o seguinte: Filma na Serra de Sintra, e junta a historia de um amor impossível entre uma rapariga e um rapaz e chama-lhe “Lua Vermelha”.

E pronto esta é a escolha dos senhores telespectadores em horário nobre… agora só falta nos “Morangos com Açúcar” surgir uma season vampiresca para o circulo ficar completo.

Ois migos! Estou a escrever um poste!

Arquivado em: drama, fail, lulz, useless — sadik @ 19:44

Olá amigos! Estou de volta após um período de hiatus (como diz a malta jovem americana). Vocês devem lembrar-se de mim de tais posts clássicos, como a criação dos memes, “Todo Fit” ou “Dia do Projecto”. Desta vez venho aqui falar de algo que realmente é importante e que é o seguinte: vampiros. Aparentemente o que está na moda hoje em dia é gostar de tudo o que esteja relacionado com vampiros. E se por acaso, esses vampiros gostarem de chupar o sangue de outros homens através da veia grossa da piça, então ainda melhor!

Vejamos:

Isto é que é um vampiro? O Nosferatu deve estar a dar voltas no caixão a esta hora (sim, porque ainda é de dia e ele provavelmente está a dormir).

Oi pessoal! Vamos falar de consolas!

Arquivado em: drama, serious-business — sadik @ 12:52

Ora viva caros amigos! Espero que a vossa cave esteja bem quentinha e com pouca humidade, pois vou falar de algo que vos vai deixar cheio de sopas de cu! Vamos falar da: XBOX 360!

Como toda a gente sabe, eu tenho uma Xbox 360 e gosto de comprar jogos originais, para ela se sentir amada. Mas há sempre pessoal que acha que comprar jogos é um desperdício de dinheiro. Acho isso relativo, há quem curta gastar guito em PDA’s e telemóveis, outros gostam de comprar o último produto da maçã mordida. No final, todos compram aquilo que gostam e o que os fazem felizes, seja X, Y ou Z. Mas gostava de saber o que é que vocês acham sobre isso. Comprar games, YAY or NAY?