<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Caloni.com.br</title>
	<link>http://www.caloni.com.br/blog</link>
	<description>C++, Windows, Programação, Depuração e Transpiração</description>
	<pubDate>Thu, 25 Feb 2010 17:39:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>Bazaar gráfico</title>
		<link>http://www.caloni.com.br/blog/archives/bazaar-grafico</link>
		<comments>http://www.caloni.com.br/blog/archives/bazaar-grafico#comments</comments>
		<pubDate>Thu, 25 Feb 2010 17:33:46 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Controle de Fonte]]></category>

		<category><![CDATA[Ferramentas]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/bazaar-grafico</guid>
		<description><![CDATA[Bom, já que por enquanto os assuntos de macho estão em falta (acabei de voltar de férias), apresento-lhes o maravilhoso mundo do Bazaar para boiolas user-friendly!
Ele é leve, vem enrustido embutido na última versão e pode economizar alguns page ups/downs no prompt do DOS. Ah, sim, antes que comentem, eu não uso o Tortoise for [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/boiola-pic.jpg" title="Boiola quem usa esses comandos pink do Bazaar…" alt="Boiola quem usa esses comandos pink do Bazaar…" width="58" align="left" height="58" />Bom, já que por enquanto os assuntos de macho estão em falta (acabei de voltar de férias), apresento-lhes o maravilhoso mundo do <a href="http://www.caloni.com.br/blog/archives/guia-basico-de-repositorios-no-bazaar" title="Guia básico do Bazaar">Bazaar</a> <strike>para boiolas</strike> <em>user-friendly</em>!</p>
<p>Ele é leve, vem <strike>enrustido</strike> embutido na última versão e pode economizar alguns <em>page ups/downs</em> no <em>prompt</em> do DOS. Ah, sim, antes que comentem, eu não uso o <a href="http://wiki.bazaar.canonical.com/TortoiseBzr" title="TortoiseBzr">Tortoise for Bazaar</a> porque instalar <a href="http://en.wikipedia.org/wiki/Shell_extension#Extensibility" title="Shell Extensions, o que são, o que comem..."><em>shell extensions</em></a>, só os muito bem feitos. (Do contrário, bem-feito para quem instalou.)</p>
<p>Para exibir a lista de comandos "amigáveis", digite no <em>prompt</em> os comandos do Bazaar filtrando-os para os que começam com "<strong>q</strong>":</p>
<pre>bzr help commands | grep ^q.*

qadd                 GUI for adding files or directories. [qbzr]
qannotate            Show the origin of each line in a file. [qbzr]
qbranch              Create a new copy of a branch. [qbzr]
qbrowse              Show inventory. [qbzr]
qcat                 View the contents of a file as of a given revision. [qbzr]
qcommit              GUI for committing revisions. [qbzr]
qconfig              Configure Bazaar. [qbzr]
qdiff                Show differences in working tree in a GUI window. [qbzr]
qgetnew              Creates a new working tree (either a checkout or full branch) [qbzr]
qgetupdates          Fetches external changes into the working tree [qbzr]
qinfo                 [qbzr]
qinit                Initializes a new (possibly shared) repository. [qbzr]
qlog                 Show log of a repository, branch, file, or directory in a Qt window. [qbzr]
qmerge               Perform a three-way merge. [qbzr]
qpull                Turn this branch into a mirror of another branch. [qbzr]
qpush                Update a mirror of this branch. [qbzr]
qrevert              Revert changes files. [qbzr]
qtag                 Edit tags. [qbzr]</pre>
<p>Os que eu mais uso no dia-a-dia são:</p>
<h4>qlog e qbrowse</h4>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/qlog.png" alt="Comando qlog do Bazaar" /></p>
<p>Diversão garantida. Por meio destes simples comandos podemos ver o histórico de commits e navegar pela árvore de pastas e arquivos com a anotação do último commit para cada elemento. Só para ter uma ideia de quanto uso isso, transformei-os em opções do Explorer.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/bzr-shell-extension.png" alt="Bazaar Shell Extension na Mão" /></p>
<p>Além da utilidade básica, de quebra, o qbrowse pode te levar para um qlog filtrado, e o qlog pode te levar a um diff gráfico, que é o próximo comando que eu iria mostrar.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/qbrowse.png" alt="Comando qbrowse do Bazaar" /></p>
<h4>qdiff</h4>
<p>Coisa linda de Deus. Existem dois modos de exibição, mas o padrão já é show de bola, mostrando as mudanças em todos os arquivos de um commit de uma só vez ou do arquivo/pasta especificado pelo comando. É lógico que é possível especificar qualquer faixa de commits que você quiser ver.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/qdiff.png" alt="Comando qdiff do Bazaar" /></p>
<p>Uma desvantagem desse comando é que ele oculta o resto das linhas do fonte e não mostra de jeito nenhum (pelo menos não descobri ainda como fazer isso). Sendo assim, para uma análise mais detalhada das diferenças no código-fonte sempre use um editor externo que consiga comparar arquivos inteiros (eu uso o WinMerge). Você pode colocar esse comando na forma de um diff personalizado, com o uso do qconfig.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/qconfig.png" alt="Comando qconfig do Bazaar" /></p>
<h4> Bônus</h4>
<p>Para quem não sabe fazer comandos de contexto no Explorer sem instalar Shell Extensions, deem uma olhada no <a href="http://www.caloni.com.br/blog/wp-content/uploads/bzr.txt" title="REG do Bazaar">REG exportado</a>.  Bom proveito.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/bazaar-grafico/feed</wfw:commentRss>
		</item>
		<item>
		<title>Restaurando o registro</title>
		<link>http://www.caloni.com.br/blog/archives/restauranto-o-registro</link>
		<comments>http://www.caloni.com.br/blog/archives/restauranto-o-registro#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:00:17 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Ferramentas]]></category>

		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/restauranto-o-registro</guid>
		<description><![CDATA[Algumas ferramentas viram essenciais quando o importante é tempo. As minhas favoritas são: Visual Studio e batch. Com esses dois eu faço virtualmente qualquer coisa que preciso em pouquíssimo tempo. É lógico que, na ausência dessas, alternativas são bem-vindas, como Notepad++, viM, grep, cygwin.
Ontem tive que resolver uma "situação" no cliente, e graças ao bom [...]]]></description>
			<content:encoded><![CDATA[<p>Algumas ferramentas viram essenciais quando o importante é tempo. As minhas favoritas são: <a href="http://www.microsoft.com/exPress/" title="Visual Studio Express">Visual Studio</a> e <a href="http://www.microsoft.com/WINDOWS/">batch</a>. Com esses dois eu faço virtualmente qualquer coisa que preciso em pouquíssimo tempo. É lógico que, na ausência dessas, alternativas são bem-vindas, como <a href="http://notepad-plus.sourceforge.net/uk/site.htm" title="Notepad++">Notepad++</a>, <a href="http://www.vim.org/" title="viM">viM</a>, <a href="http://gnuwin32.sourceforge.net/" title="GNU Tools for Windows">grep</a>, <a href="http://www.cygwin.com/" title="CygWin">cygwin</a>.</p>
<p>Ontem tive que resolver uma "situação" no cliente, e graças ao bom Deus (ele também é programador) existia um Notepad++ na bagagem que levávamos. Além, é claro, do Excel e do sistema batch do Windows.</p>
<p>O problema consistia basicamente em usar a saída do <a href="http://technet.microsoft.com/en-us/sysinternals/bb896652.aspx" title="RegMon is not available">RegMon</a> para identificar e restaurar algumas modificações que danificavam a instalação do Internet Explorer. O sistema de reparo do IE não existia no cliente, pois ele estava sem Service Pack (bem-vindo ao mundo real), mas podíamos nos guiar através dele na nossa máquina virtual para saber o que faríamos. O estrago era feito durante o registro e/ou desregistro de um componente COM.</p>
<blockquote><p><em>Aliás, não, eu não preciso usar o onipresente e onipotente Process Monitor para resolver um detalhezinho no registro. Você talvez precise, já que a Microsoft já tirou o Reg e o File de circulação.</em></p></blockquote>
<p>Para iniciar, filtramos os resultados do RegMon para apenas capturar escritas no registro, não importando se falharam ou deram resultado.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/regmon-filter.png" alt="Filtro no RegMon" /></p>
<p>A partir disso executamos o registro e desregistro do componente, além da restauração do IE6, responsável por limpar a bagunça. O processo responsável por registrar componentes é o <strong>regsvr32</strong> e o responsável por limpar a bagunça, <strong>rundll32</strong>.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/iexplore-restore.png" alt="Restauração do IExplore" /></p>
<p>Tendo a saída do RegMon exportada para formato texto, abrimos no Excel e filtramos o conteúdo pelo nome do processo. Note que existem duas instâncias de regsvr32 para usar, pois não sabemos em qual delas é danificado o registro.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/excel-filter.png" alt="Filtro no Excel" /></p>
<p>Para cada um dos filtros copiamos apenas o endereço da chave alterada para dois arquivos texto: regsvr32.txt e ierestore.txt. Usaremos esse primeiro para encontrar ocorrências no segundo, provando que um modifica o que o outro consertou.</p>
<p>Existe um comando muito simplório em batch Windows que é o aplicativo <strong>find</strong>. Através dele podemos encontrar a ocorrência de uma string em um arquivo. Para transformar todas aquelas linhas do registro do arquivo regsvr32 em comandos find poderíamos elaborar algumas colunas no Excel ou usar o Notepad++ e suas macros, mais rápidas.</p>
<p>Para quem não conhece macros, saiba que elas são muito úteis. Às vezes até mais úteis que "regexes", pois não é necessário pensar muito na expressão a ser usada. Macros apenas repetem os movimentos do teclado que fazemos enquanto as estamos gravando. Por exemplo, eu tenho o meu monte de linhas de registro assim:</p>
<pre>HKLM\SOFTWARE\Microsoft\Cryptography\RNG
HKLM\SOFTWARE\Microsoft\Cryptography\RNG\Seed
HKCR\AppID\{EE62DE09-3A23-46DB-8FA2-266088F329CD}
HKCR\AppID\{EE62DE09-3A23-46DB-8FA2-266088F329CD}\(Default)
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{C322BA70-E3E7-4737-821C-D25378A3F830}
HKCR\CLSID\{684E2452-19E1-42CC-9C93-A83044BA1AF2}
HKCR\CLSID\{684E2452-19E1-42CC-9C93-A83044BA1AF2}\Programmable
...</pre>
<p>Quero transformar cada linha em um comando find. Iniciou a gravação da macro no início da primeira linha e digito o seguinte (em pseudo-alguma-coisa):</p>
<p>find, espaço, abre aspas, end, fecha aspas, espaço, ierestore.txt, linha abaixo, home</p>
<pre>find "HKLM\SOFTWARE\Microsoft\Cryptography\RNG" ierestore.txt
HKLM\SOFTWARE\Microsoft\Cryptography\RNG\Seed
HKCR\AppID\{EE62DE09-3A23-46DB-8FA2-266088F329CD}</pre>
<p>Pronto. Parar macro. Terei que repetir isso dois milhões de vezes até o final do arquivo. Ora, então mando o Notepad++ repetir a minha macro até o final do arquivo e adio minha tendinite para os próximos anos.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/notepadpp-filter.png" alt="Filtro no Notepad++" /></p>
<p>Só preciso agora renomear meu arquivo para .bat e executar. Posso redirecionar a saída da tela para um terceiro arquivo, de onde irei formatar minha lista de entradas no registro que foram adulteradas por ambos os programas (o registro do componente COM e a restauração do Internet Explorer).</p>
<p>Nesse momento podemos ir tomar café. Bem melhor do que ficar horas e horas dando localizar, copiar, colar em todas as entradas do regsvr.</p>
<p><a href="http://www.caloni.com.br/blog/archives/restauranto-o-registro/tomando-cafe/" rel="attachment wp-att-846" title="Tomando café"><img src="http://www.caloni.com.br/blog/wp-content/uploads/taking-coffee-notepadpp.jpg" alt="Tomando café" /></a></p>
<p>Terminada a operação, abrimos o terceiro arquivo, retiramos as entradas insignificantes (por exemplo, o gerador de sementes de números randômicos) e os cabeçalhos do comando, algo bem fácil já que se trata do mesmo arquivo.</p>
<pre>---------- IERESTORE.TXT
---------- IERESTORE.TXT
---------- IERESTORE.TXT
---------- IERESTORE.TXT
...</pre>
<p>A próxima tarefa seria analisar cada entrada e ver se ela é relevante. Essa parte foi manual, mas, encontrado um padrão, listamos rapidamente o que poderia estar dando errado e criamos uma lista de entradas para exportar do registro "sadio" a fim de gerar um .REG que corrigiria sistemas danificados.</p>
<p>Algumas passadas no Notepad++ para eliminar linhas duplicadas e algumas passadas pelo cérebro para eliminar chaves redundantes (chave dentro de chave) e tcharam!</p>
<pre>...
HKCR\Interface\{3050F2E3-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F2E5-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F32D-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F357-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F35C-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F37E-98B5-11CF-BB82-00AA00BDCE0B}
HKCR\Interface\{3050F38C-98B5-11CF-BB82-00AA00BDCE0B}
...</pre>
<p>O próximo passo para nossa obra-prima é outra macro que irá reproduzir o comando reg, que pode realizar operações no registro do Windows.</p>
<pre>...
reg export HKCR\Interface\{3050F240-98B5-11CF-BB82-00AA00BDCE0B} 3050F240-98B5-11CF-BB82-00AA00BDCE0B.reg
reg export HKCR\Interface\{3050F25A-98B5-11CF-BB82-00AA00BDCE0B} 3050F25A-98B5-11CF-BB82-00AA00BDCE0B.reg
reg export HKCR\Interface\{3050F25E-98B5-11CF-BB82-00AA00BDCE0B} 3050F25E-98B5-11CF-BB82-00AA00BDCE0B.reg
reg export HKCR\Interface\{3050F2E3-98B5-11CF-BB82-00AA00BDCE0B} 3050F2E3-98B5-11CF-BB82-00AA00BDCE0B.reg
reg export HKCR\Interface\{3050F2E5-98B5-11CF-BB82-00AA00BDCE0B} 3050F2E5-98B5-11CF-BB82-00AA00BDCE0B.reg
reg export HKCR\Interface\{3050F32D-98B5-11CF-BB82-00AA00BDCE0B} 3050F32D-98B5-11CF-BB82-00AA00BDCE0B.reg
...</pre>
<pre></pre>
<p>E o último passo é juntar toda essa galera em um arquivo só.</p>
<pre>copy *.reg ierestore.reg</pre>
<p>Claro, não se esqueça de retirar os cabeçalhos duplicados (Windows Registry Editor Version X.XX). E Voilà! Fácil, não? Não?! Bom, então é por isso que eu sou bem pago =)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/restauranto-o-registro/feed</wfw:commentRss>
		</item>
		<item>
		<title>Correção de bugs instantânea</title>
		<link>http://www.caloni.com.br/blog/archives/correcao-de-bugs-instantanea</link>
		<comments>http://www.caloni.com.br/blog/archives/correcao-de-bugs-instantanea#comments</comments>
		<pubDate>Mon, 01 Feb 2010 09:00:53 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/correcao-de-bugs-instantanea</guid>
		<description><![CDATA[Um programador tarimbado sabe que a melhor situação da vida dele para corrigir um bug é quando esse bug acontece em sua máquina de desenvolvimento, na versão Debug e ainda passo-a-passo. Como nessa situação a correção é um verdadeiro "passeio no parque" (ou na mesa do café) ela tende a quase nunca acontecer. Isso é [...]]]></description>
			<content:encoded><![CDATA[<p>Um programador tarimbado sabe que a melhor situação da vida dele para corrigir um bug é quando esse bug acontece em sua máquina de desenvolvimento, na versão Debug e ainda passo-a-passo. Como nessa situação a correção é um verdadeiro "passeio no parque" (ou na mesa do café) ela tende a quase nunca acontecer. Isso é <a href="http://www.caloni.com.br/blog/wp-admin/Corre%C3%A7%C3%A3o%20de%20bugs%20instant%C3%A2nea.txt">Murphy</a> Aplicado.</p>
<p>Para quem programa para sistemas, então, só o fato de acontecer no mesmo processo toda vez que ele for executado já é o máximo (quem já programou serviços, plugins, GINAs e afins sabe do que eu estou falando).</p>
<p>Porém, saber que uma determinada situação é mel na chupeta (by <a href="http://codebehind.wordpress.com">Thiago</a>) por si só não adianta de muita coisa. É preciso conhecer as verdadeiras técnicas ninjas que conseguem resolver um bug escabroso num instante, coisa de deixar seu gerente de projetos tão feliz ao ponto dele não botar nenhum defeito na solução.</p>
<p>Dentre as mais conhecidas entre os <a href="http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/">malloqueiros</a>, temos:</p>
<ul>
<li>Comenta-descomenta-comenta</li>
<li>Faz do zero</li>
</ul>
<p>Essas duas técnicas são tão úteis e tão fáceis de usar que merecem um artigo a respeito.</p>
<h4>Tira-põe-deixa-ficar</h4>
<p>Essa técnica milenar corresponde em tirar pedaços do código-fonte que poderiam estar causando o problema até que seja possível criar uma versão em que o problema não ocorra mais. Quando chega-se nesse nível, então volta-se a descomentar o código retirado até que o problema ocorra novamente. O processo é um fluxo de tira-código com volta-código, sendo que é necessário o bom conhecimento do projeto para não gerar outros problemas com a mutilação temporária do projeto.</p>
<h4>Projeto-esqueleto (<a href="http://pt.wikipedia.org/wiki/He-Man">Re</a>-<a href="http://en.wikipedia.org/wiki/Main_function_%28programming%29">Main</a>!)</h4>
<p>Se o código começa a ser tão mutilado que chegamos quase em uma versão vazia (sem código), então talvez a melhor forma de atacar o problema seja criar um esqueleto que contenha apenas o código necessário para que ele não faça nada. Isso mesmo. Não fazendo nada, mas instalado. Com isso prova-se que é possível estar lá sem fazer cagadas. A partir daí vai colocando-se o código do projeto real aos poucos no projeto-esqueleto, até que ele apresente o problema. Ou não. Já vi casos em que todo o código foi migrado e o problema sumiu. <em>Ce la vie</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/correcao-de-bugs-instantanea/feed</wfw:commentRss>
		</item>
		<item>
		<title>House</title>
		<link>http://www.caloni.com.br/blog/archives/house</link>
		<comments>http://www.caloni.com.br/blog/archives/house#comments</comments>
		<pubDate>Mon, 25 Jan 2010 09:00:48 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/house</guid>
		<description><![CDATA[Depois da analogia entre depuração e CSI, nada como fazer o mesmo com o seriado estilo House.
Quais as semelhanças com a profissão de programador-depurador?
Em primeiro lugar, a busca por pistas. Se algo está errado com o programa, vivemos criando teorias mirabolantes a respeito do porquê tal função estar retornando zero. No entanto, como não temos [...]]]></description>
			<content:encoded><![CDATA[<p>Depois da <a href="http://www.caloni.com.br/blog/archives/csi-crashed-server-investigation">analogia entre depuração e CSI</a>, nada como fazer o mesmo com o seriado <a href="http://pt.wikipedia.org/wiki/House,_M.D." title="House M.D.">estilo House</a>.</p>
<p>Quais as semelhanças com a profissão de programador-depurador?</p>
<p>Em primeiro lugar, a <strong>busca por pistas</strong>. Se algo está errado com o programa, vivemos criando teorias mirabolantes a respeito do porquê tal função estar retornando zero. No entanto, como não temos tanta capacidade adivinhatória assim, geralmente nossos palpites estão errados, e o fundo do poço irá nos mostrar uma outra função que nem estava ainda na história.</p>
<p>Mas existem alguns pontos-comuns de conhecimento que sempre desenvolvemos no decorrer da carreira:</p>
<ul>
<li>Se a última instrução do código é zero (ou algo próximo disso), provavelmente a pilha foi corrompida por alguém que tentou zerar uma variável, e junto dela o ponto de retorno de alguma função chamadora.</li>
<li>Se um programa trava em um determinado momento, voltando após um período previsível de tempo (30 segundos), automaticamente sabemos que existe algum evento/mutex usado de forma errada que, dadas as circunstâncias, apresentou uma espera longa demais.</li>
<li>Se uma versão nova capota em um procedimento em que a versão antiga nunca capotou, podemos divagar rapidamente quais as características da nova versão que fizeram com que isso acontecesse, ainda sem olhar para o código.</li>
</ul>
<p>Dessa forma é possível criar teorias a partir da análise mental do que o programa normal <strong>deveria estar fazendo</strong>, mas não está. É esse tipo de análise que é feita no seriado.</p>
<p>Porém, o lado bom: podemos testar todas nossas hipóteses. Na vida real! Se, por enquanto, matar pacientes para depois ressuscitá-los é coisa de ficção, matar sistemas e reiniciá-los não é. E, dependendo do problema, podemos sempre replicá-lo em "outro paciente".</p>
<p>Talvez isso faça a profissão tão realizadora e viciante: para resolver um problema, geralmente temos todas as cartas na mão, e se não temos, fazemos ter. Afinal de contas, somos nós que iremos ressuscitar o sistema perdido.</p>
<h4>Leituras Relacionadas</h4>
<ul>
<li><a href="http://compare.buscape.com.br/categoria?id=3482&amp;lkout=1&amp;kw=ciencia+media+house&amp;site_origem=1293522" title="A Ciência Média de House no Buscapé">A Ciência Médica de House </a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/house/feed</wfw:commentRss>
		</item>
		<item>
		<title>Passagem por valor e emails com anexo</title>
		<link>http://www.caloni.com.br/blog/archives/passagem-por-valor-e-emails-com-anexo</link>
		<comments>http://www.caloni.com.br/blog/archives/passagem-por-valor-e-emails-com-anexo#comments</comments>
		<pubDate>Mon, 18 Jan 2010 09:00:22 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/passagem-por-valor-e-emails-com-anexo</guid>
		<description><![CDATA[Mais uma analogia vencedora para ponteiros, chamadas por valor e chamadas por referência: e-mails.
Quando passamos um parâmetro por valor, estamos enviando um e-mail com um arquivo em anexo. Não importa o que o destinatário faça com o arquivo: nós não vamos saber o que foi mudado se ele não enviar uma outra cópia.

Por outro lado, [...]]]></description>
			<content:encoded><![CDATA[<p>Mais uma analogia vencedora para ponteiros, chamadas por valor e chamadas por referência: e-mails.</p>
<p>Quando passamos um parâmetro por valor, estamos enviando um e-mail com um arquivo em anexo. Não importa o que o destinatário faça com o arquivo: nós não vamos saber o que foi mudado se ele não enviar uma outra cópia.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/email-para-funcao.png" alt="email-para-funcao.png" /></p>
<p>Por outro lado, ao passar um parâmetro por referência, estamos enviando um e-mail com um <strong>endereço</strong> de onde está o arquivo. Se o usuário alterar o arquivo diretamente do endereço que enviamos será possível ver essa alteração imediatamente, pois ambos estão olhando para o mesmo valor na memória.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/email-para-funcao2.png" alt="email-para-funcao2.png" /></p>
<p>A analogia pode ser levada mais longe, com ponteiros de ponteiros: enviamos um e-mail com o endereço de um arquivo; dentro desse arquivo existe um endereço para outro arquivo. Dessa forma é possível tanto alterar o arquivo final quanto o endereço de onde ele está; ou ainda "apontar" para outro arquivo, trocando o endereço de dentro do primeiro arquivo.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/email-para-funcao3.png" alt="email-para-funcao3.png" /></p>
<p>Assim é fácil de visualizar que os dados estão sempre em um arquivo que ocupa espaço na memória (do disco ou da RAM), mas endereços também podem ocupar espaço, se estiverem salvos em um arquivo.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/novo-arquivo.png" alt="novo-arquivo.png" /></p>
<p>Dessa forma, um e-mail que contenha um arquivo em anexo vai ser muito maior que um e-mail apenas com o endereço do arquivo, mas é porque todo o conteúdo do arquivo está dentro do e-mail no primeiro caso. No segundo caso, o endereço ocupa apenas alguns caracteres que identificam a localização do arquivo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/passagem-por-valor-e-emails-com-anexo/feed</wfw:commentRss>
		</item>
		<item>
		<title>Importando tipos de outros projetos</title>
		<link>http://www.caloni.com.br/blog/archives/importando-tipos-de-outros-projetos</link>
		<comments>http://www.caloni.com.br/blog/archives/importando-tipos-de-outros-projetos#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:07:37 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Engenharia Reversa]]></category>

		<category><![CDATA[Sistema Operacional]]></category>

		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/importando-tipos-de-outros-projetos</guid>
		<description><![CDATA[A engenharia reversa das entranhas do kernel não tem limites se você sabe o que está fazendo. No entanto, algumas facilidades do depurador podem ajudar a minimizar o tempo que gastamos para analisar uma simples estrutura. Por exemplo, o Process Environment Block de um processo específico.
windbg -kl

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>A engenharia reversa das entranhas do kernel não tem limites se você sabe o que está fazendo. No entanto, algumas facilidades do depurador podem ajudar a minimizar o tempo que gastamos para analisar uma simples estrutura. Por exemplo, o <a href="http://msdn.microsoft.com/en-us/library/aa813706%28VS.85%29.aspx" title="PEB da Microsoft">Process Environment Block</a> de um processo específico.</p>
<pre>windbg -kl

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Symbol search path is: SRV*c:\tools\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
*******************************************************************************
WARNING: Local kernel debugging requires booting with kernel
debugging support (/debug or bcdedit -debug on) to work optimally.
*******************************************************************************
Windows XP Kernel Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.090804-1435
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055d720
Debug session time: Mon Jan 11 10:36:50.061 2010 (GMT-2)
System Uptime: 5 days 1:05:24.958

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

lkd&gt; !process 0 0 notepad.exe
<font color="#0000ff">PROCESS 89068700 </font> SessionId: 0  Cid: 0ec4   <font color="#0000ff"> Peb: 7ffda000</font>  ParentCid: 0b0c
    DirBase: 0ac80a80  ObjectTable: e143a7d8  HandleCount: 152.
    Image: notepad.exe</pre>
<p>O comando <a href="http://windbg.info/doc/1-common-cmds.html#11_process" title="Comando !peb no Windbg.info">!peb</a> traz inúmeras informações sobre essa estrutura. Mas talvez estivéssemos interessados em coisas não mostradas por esse comando, mas <a href="http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html" title="PEB ">que existem na estrutura</a>.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/peb-undocumented.png" alt="PEB “não-documentado”" /></p>
<p>Nesse caso, podemos criar um projeto vazio que contenha a definição da estrutura <strong>como acreditamos</strong> que esteja na versão do kernel que estamos depurando.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/mypeb.png" alt="MyPEB" /></p>
<p>Compilamos e geramos um PDB (arquivo de símbolos) que contém a definição desse tipo. Tudo que precisamos fazer agora é carregar esse símbolo na sessão que estivermos depurando.</p>
<p>É claro que nosso executável não vai existir na sessão de kernel local, mas isso não importa. Podemos usar qualquer módulo carregado e usá-lo como <em>host </em>de nosso conjunto de símbolos:</p>
<pre>lkd&gt; lm
start    end        module name
804d7000 806e5000   nt         (pdb symbols)          c:\tools\symbols\ntkrpamp.pdb\D8743252F83B4F59985D6E19F33BFCAF1\ntkrpamp.pdb

Unloaded modules:
a5513000 a553e000   kmixer.sys
<font color="#0000ff">bac50000 bac57000   USBSTOR.SYS</font>
a5711000 a5746000   truecrypt.sys
a5731000 a5746000   wudfrd.sys
a5a19000 a5a23000   wpdusb.sys
...
a5731000 a5746000   wudfrd.sys
a57a9000 a57b3000   wpdusb.sys
a571b000 a5746000   kmixer.sys
babf0000 babf5000   Cdaudio.SYS
ba489000 ba48c000   Sfloppy.SYS
babe8000 babed000   Flpydisk.SYS
babe0000 babe7000   Fdc.SYS 

------ Build started: Project: KernelTypes, Configuration: Debug Win32 ------
Compiling...
KernelTypes.cpp
Linking...
LINK : program database c:\Tests\KernelTypes\Debug\<font color="#0000ff">KernelTypes.pdb</font> missing; performing full link
Embedding manifest...
Build log was saved at "file://c:\Tests\KernelTypes\Debug\BuildLog.htm"
KernelTypes - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Microsoft Windows XP [versÎáÎ÷Îýo 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Tests\KernelTypes\Debug&gt;ren KernelTypes.pdb <font color="#0000ff">usbstor.pdb</font>

lkd&gt; .sympath C:\Tests\KernelTypes\Debug
Symbol search path is: C:\Tests\KernelTypes\Debug
<font color="#0000ff">lkd&gt; .reload /i /f usbstor.sys</font>
lkd&gt; lm m usb*
start    end        module name
bac60000 bac66700   USBSTOR  M (private pdb symbols)  <font color="#0000ff">C:\Tests\KernelTypes\Debug\usbstor.pdb</font></pre>
<p>Depois que o símbolo foi carregado em nosso módulo de mentirinha, tudo que temos a fazer é alterar o contexto do processo atual (para que os endereços de user mode façam sentido) e moldar nossa memória com o comando <a href="http://windbg.info/doc/1-common-cmds.html#12_thread" title="Thread related commands">dt</a>, usando o tipo importado do símbolo carregado.</p>
<pre>lkd&gt; .process 89068700
Implicit process is now 89068700
lkd&gt; dt <font color="#0000ff">usbstor!_peb</font> 7ffda000
   +0x000 InheritedAddressSpace : 0xdc ''
   +0x001 ReadImageFileExecOptions : 0xff ''
   +0x002 BeingDebugged    : 0x35 '5'
   +0x003 SpareBool        : 0x1 ''
   +0x004 Mutant           : 0x01360000
   +0x008 ImageBaseAddress : 0x0135e000
   +0x00c Ldr              : (null)
   +0x010 ProcessParameters : 0x00001e00 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : (null)
   +0x018 ProcessHeap      : 0x7ffda000
   +0x01c FastPebLock      : (null)
   +0x020 SparePtr1        : 0x00000efc
   +0x024 SparePtr2        : 0x000008b8
   +0x028 EnvironmentUpdateCount : 0
   +0x02c KernelCallbackTable : (null)
   +0x030 SystemReserved   : [1] 0x7ffde000
   +0x034 ExecuteOptions   : 0y00
   +0x034 SpareBits        : 0y000000000000000000000011111100 (0xfc)
   +0x038 FreeList         : (null)
   +0x03c TlsExpansionCounter : 0
...</pre>
<p>Para que isso funcione, a estrutura definida tem que bater offset por offset com os dados na memória, o que envolve alinhamento (se lembre do <a href="http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx" title="Pragma pack no MSDN">pragma pack</a>) e versionamento corretos. Se isso não ocorrer, logo aparecerá algum lixo nos membros da estrutura que não fará sentido. Se isso ocorrer, detecte onde o lixo começa e verifique se o membro existe nessa versão do sistema operacional, ou se o alinhamento está de acordo com o módulo analisado.</p>
<p>Acho que não é preciso dizer que isso não serve apenas para kernel mode =)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/importando-tipos-de-outros-projetos/feed</wfw:commentRss>
		</item>
		<item>
		<title>Devaneio nerd rápido sobre profecias</title>
		<link>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-profecias</link>
		<comments>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-profecias#comments</comments>
		<pubDate>Wed, 30 Dec 2009 18:24:35 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-profecias</guid>
		<description><![CDATA[Para quem já analisou os dados de uma tela azul sabe que, quando o Windows acha um culpado (vulgo driver) a data de sua compilação é exibida em um formato conhecido como DateStamp ou TimeStamp. Nesse formato o que temos é um número hexadecimal que segue o formato de tempo do Unix, que no caso [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/crystallball.jpg" title="crystallball.jpg" alt="crystallball.jpg" align="left" />Para quem já analisou os dados de uma tela azul sabe que, quando o Windows acha um culpado (vulgo driver) a data de sua compilação é exibida em um formato conhecido como <strong>DateStamp</strong> ou <strong>TimeStamp</strong>. Nesse formato o que temos é um número hexadecimal que segue o <a href="http://en.wikipedia.org/wiki/Unix_timestamp">formato de tempo do Unix</a>, que no caso é o número de segundos desde o dia primeiro de Janeiro de 1970. Isso, por curiosidade, nos dá uma margem de 140 anos antes dos número se repetirem se usarmos 32 bits nessa contagem.</p>
<p>O comando .formats do WinDbg nos consegue trazer desse número a hora exata em que determinado componente foi compilado. Se, por exemplo, um driver faltoso apresentou um DateStamp igual a 49EE9758, podemos concluir que ele foi compilado no dia 22 de abril de 2009, uma linda quarta-feira.</p>
<pre>0:000&gt; <font color="#0000ff">.formats 49EE9758</font>
Evaluate expression:
  Hex:     00000000`49ee9758
  Decimal: 1240373080
  Octal:   0000000000011173513530
  Binary:  00000000 00000000 00000000 00000000 01001001 11101110 10010111 01011000
  Chars:   ....I..X
<strong><font color="#0000ff">  Time:    Wed Apr 22 01:04:40 2009</font></strong>
  Float:   low 1.95454e+006 high 0
  Double:  6.12826e-315</pre>
<p>Quando fazemos algo muitas vezes seguidas temos o hábito inconsciente de observar certas idiossincrasias dos dados que sempre vem e vão. No caso dos Date Stamps, sempre me veio o fato deles iniciarem com 4 e estarem prestes a "virar o contador" para 5.</p>
<p>Isso aos poucos - entre uma tela azul e outra - me deixou curioso a respeito de quando seria o dia fatídico em que teríamos o DateStamp 50000000, um número cabalístico em nosso sistema decimal. E, imaginem só:</p>
<pre>0:000&gt; <font color="#0000ff">.formats 50000000</font>
Evaluate expression:
  Hex:     00000000`50000000
  Decimal: 1342177280
  Octal:   0000000000012000000000
  Binary:  00000000 00000000 00000000 00000000 01010000 00000000 00000000 00000000
  Chars:   ....P...
<font color="#0000ff">  Time:    Fri Jul 13 08:01:20 2012</font>
  Float:   low 8.58993e+009 high 0
  Double:  6.63124e-315</pre>
<p>Pois é, meus amigos. O DateStamp para a virada do contador Unix se fará numa manhã de sexta. Para ser preciso, uma <a href="http://pt.wikipedia.org/wiki/Sexta_Feira_13">sexta-feira 13</a>.</p>
<p>Curioso, não? Mais curioso que isso, só sabendo que o ano que isso vai ocorrer é o igualmente fatídico <a href="http://www.youtube.com/watch?v=Hz86TsGx3fc">2012</a>. Felizmente antes de dezembro.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-profecias/feed</wfw:commentRss>
		</item>
		<item>
		<title>Devaneio nerd rápido sobre aniversários</title>
		<link>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-aniversarios</link>
		<comments>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-aniversarios#comments</comments>
		<pubDate>Mon, 14 Dec 2009 10:10:45 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-aniversarios</guid>
		<description><![CDATA[Hoje não é aniversário do blogue. É meu. Há exatos (sic) trinta anos nascia eu, essa pessoa que vos fala. Legal, não?
Beeeem legal. Tão legal quanto saber que o núcleo de um átomo representa 99,9% de sua masssa ou que uma borboleta bate duzentas mil vezes a asa por hora (só chutando, eu não sei [...]]]></description>
			<content:encoded><![CDATA[<p>Hoje não é aniversário do blogue. É meu. Há exatos (<a href="http://pt.wikipedia.org/wiki/Ano">sic</a>) trinta anos nascia eu, essa pessoa que vos fala. Legal, não?</p>
<p>Beeeem legal. Tão legal quanto saber que o núcleo de um átomo representa 99,9% de sua masssa ou que uma borboleta bate duzentas mil vezes a asa por hora (só chutando, eu não sei realmente).</p>
<p>Ou saber, talvez, que o homem deciciu contar sua idade terrena através do número de vezes que esse planetinha gira em órbita de sua estrela. É o tipo de curiosidade mais que suficiente para comentar em sua quinquagésima festa de aniversário durante a rodinha do tédio (aquela em que você não tem  nada pra comentar porque já é a quinquagésima festinha do ano e as pessoas já estão cansadas de se verem).</p>
<blockquote><p><em>Dr. House: Ah, my birthday. Normally I'd put on a festive hat and celebrate the fact that the Earth has circled the Sun one more time; I really didn't think it was going to make it this year, but darn it if it wasn't the little planet that could all over again. (1.06 <a href="http://en.wikiquote.org/wiki/House_%28TV_series%29#The_Socratic_Method_.281.06.29">The Socratic Method</a>)</em></p></blockquote>
<p>Do ponto de vista estatístico (sempre ela!), então, nem se fala. Na região onde eu moro vivem dez milhões de pessoas. Em uma conta de padaria, trinta mil fazem aniversário junto comigo. Na mesma hora, talvez umas mil. Bom, mas existem sessentas minutos em uma hora! Dessa forma, eu tenho a chance de ter nascido no mesmo minuto junto de cerca de vinte rebentos. Ah, e os segundos!?!? É verdade. Sou obrigado a torcer o nariz para o "fato" que tenho mais de 50% de chance de ser a única pessoa na região de São Paulo a ter nascido no mesmo segundo. Que especial! Bom, no mundo inteiro, é óbvio que não tenho nem um milissegundo pra mim, o que torna a data tão insignificativa quanto um alerta do <a href="www.orkut.com">orkut</a> sobre a mesma.</p>
<ul>
<li>Se aplicarmos a mesma lógica matemática à morte e aos nascimentos chegaremos à inevitável (e óbvia) equação que a vida de um indivíduo para a nossa espécie hoje em dia vale menos que sua aposentadoria. Até porque, dessa imensa maioria de pessoas que nascem e morrem, a maioria é pobre e não tem condições de contribuir com uma boa parcela de gastos para o bem de nossa economia. A maioria é burra também, e pode contribuir menos ainda pelo valor agregado de nossa riqueza.</li>
</ul>
<ul>
<li>Me foi contado que aniversários são eventos para celebrar a vida, principalmente do aniversariante. Ótimo! Isso quer dizer que a vida de cada um vale menos de 0,3% do ano inteiro, já que reservamos apenas um dia em 360 para confirmar que ainda estamos respirando.</li>
</ul>
<p>Bom, esse artigo já devanou demais. E como meu objetivo nem foi chegar à uma conclusão, termino por aqui. Ah, para dar mais corda pra pensar: feliz <a href="http://pt.wikipedia.org/wiki/Natal">natal</a>!</p>
<p>PS: Mensagens de feliz aniversário serão devidamente descartadas. Ah, e feliz <a href="http://pt.wikipedia.org/wiki/Ano-Novo">ano-novo</a> pra você, também.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/devaneio-nerd-rapido-sobre-aniversarios/feed</wfw:commentRss>
		</item>
		<item>
		<title>Aprendendo um terceiro idioma</title>
		<link>http://www.caloni.com.br/blog/archives/aprendendo-um-terceiro-idioma</link>
		<comments>http://www.caloni.com.br/blog/archives/aprendendo-um-terceiro-idioma#comments</comments>
		<pubDate>Fri, 11 Dec 2009 09:00:39 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/aprendendo-um-terceiro-idioma</guid>
		<description><![CDATA[Inspirado pelo texto de Chad Fowler que explica como o aprendizado de um segundo idioma mudou sua vida (sua língua-mãe é o inglês americano), resolvi descrever brevemente o que foi o momento da minha vida que decidi que iria tentar aprender Russo. Lógico, sem todo o folclore e a experiência de vida do autor do [...]]]></description>
			<content:encoded><![CDATA[<p>Inspirado pelo <a href="http://www.chadfowler.com/2009/8/2/how-learning-a-second-language-changed-my-life">texto</a> de Chad Fowler que explica como o aprendizado de um segundo idioma mudou sua vida (sua língua-mãe é o inglês americano), resolvi descrever brevemente o que foi o momento da minha vida que decidi que iria tentar aprender Russo. Lógico, sem todo o folclore e a experiência de vida do autor do original.</p>
<p>Primeiro, meus motivos primários:<br />
- Estava escutando <a href="http://www.tatugirls.com/">Tatu</a>;<br />
- Costumava conversar pelo ICQ com uma amiga de Moscou (em inglês, apesar dela falar mais três ou quatro idiomas; e ela só tinha 19 anos!);<br />
- Estava querendo aproveitar parte do meu cérebro que fica inerte a maior parte do tempo porque meu emprego basicamente só mexe com coisas (quase) lógicas, como programação;<br />
- Achava uma língua bem bonita e exótica;<br />
- <strike>Gosto de jogar xadrez (o que isso tem a ver?)</strike>.</p>
<p>Bom, no início comecei aprendendo o alfabeto. Alguns podem dizer que não há nenhum segredo no <a href="http://pt.wikipedia.org/wiki/Alfabeto_cir%C3%ADlico">cirílico</a>, e de fato não há. Porém, uma coisa é saber <strong>interpretar </strong>mais ou menos aquelas letrinhas derivadas do grego; outra completamente diferente é saber <strong>escrever </strong>em letra de base e em letra de mão todos os 33 caracteres, e ainda saber de cor o <a href="http://www.codeproject.com/KB/winsdk/ruskey.aspx">leiaute do teclado russo</a>. Isso leva um pouco de tempo, e é bem divertido!</p>
<p>A partir daí passei cerca de seis meses apenas treinando a escrita e leitura do cirílico, aprendendo a diferença de som dependendo do contexto, um caderno a tiracolo no meio do ônibus, do trem e do metrô escrevendo infinitas linhas incompreensível provavelmente por 99% das pessoas que cruzavam meu caminho e olhavam curiosas.</p>
<p>Depois, o idioma em si. Nessa fase resolvi apelar para <a href="http://www.cursoderusso.com/">um curso disponível no mosteiro S. Bento</a> ministrado por uma russa autência, de S. Petersburgo. Ela não falava muito bem português, o que para mim era um "plus".</p>
<p>Passei mais seis meses de curso com ela e com alguns textos que ia baixando da internet. Depois do curso comprei um curso em áudio e texto que fui acompanhando morosamente pelo resto dos dois anos que passei me aventurando pelo idioma.</p>
<p>No meio do caminho um amigo meu achou o podcast <a href="http://speakrussian.blogspot.com/">Spoonful of Russian</a>, o que foi uma diversão só, especialmente pelo conhecimento cultural e musical do povo russo. Minha amiga também me enviou alguns CDs de bandas russas famosas, e fiquei especialmente encantando com <a href="http://en.wikipedia.org/wiki/Ivan_Kupala_%28musical_project%29">Ivan Kupala</a>, que até hoje escuto. Se trata de uma banda que pegou músicas do folclore russo e adaptou para os tempos atuais, mas cantado ainda por velhinhas e velhinhos que aparentemente parecem ter saído de uma aldeia dos Montes Urais.</p>
<p>O cinema e a BBC russa também representaram um instrumento de aprimoramento do listening do dia-a-dia. Uma coisa é escutar um russo falando devagar durante uma aula de declinação do futuro por aspecto. Outra coisa é ver alguém usando isso enquanto atravessa a rua conversando com um amigo no meio do barulho da cidade grande, ou uma mulher que mais parece uma metralhadora disparando 500 notícias de uma vez no podcast de um jornal da internet.</p>
<p>Infelizmente, essa fase esmaeceu. Agora estou muito interessado em finanças e isso fez com que o russo ficasse cada vez mais para trás. Se me pedir hoje para falar algo em russo vou conseguir apenas balbuciar as mais "comunzinhas", pois esqueci todo o resto. Foi perda de tempo? Claro que não! Foi uma experiência que mostra que podemos aprender qualquer coisa a qualquer hora, independente do quão estranho ou bizarro isso seja.</p>
<p>до свидание!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/aprendendo-um-terceiro-idioma/feed</wfw:commentRss>
		</item>
		<item>
		<title>O boot no Windows: Kernel</title>
		<link>http://www.caloni.com.br/blog/archives/o-boot-no-windows-kernel</link>
		<comments>http://www.caloni.com.br/blog/archives/o-boot-no-windows-kernel#comments</comments>
		<pubDate>Fri, 04 Dec 2009 18:13:57 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Engenharia Reversa]]></category>

		<category><![CDATA[Sistema Operacional]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/o-boot-no-windows-kernel</guid>
		<description><![CDATA[Finalmente chegamos em um pouco onde podemos usar o WinDbg.
Podemos espetar o depurador e fazê-lo parar assim que conectado. Se estiver rodando antes do próprio sistema operacional, teremos um sistema sem processos e sem threads, pois ele irá parar assim que o executivo puder enviar o sinal de início pela porta serial, após carregar na [...]]]></description>
			<content:encoded><![CDATA[<p>Finalmente chegamos em um pouco onde podemos usar o WinDbg.</p>
<p>Podemos espetar o depurador e fazê-lo parar assim que conectado. Se estiver rodando antes do próprio sistema operacional, teremos um sistema sem processos e sem threads, pois ele irá parar assim que o executivo puder enviar o sinal de início pela porta serial, após carregar na memória os módulos básicos.</p>
<pre>windbg -k com:pipe,port=\\.\pipe\com_1 <strong><font color="#000000">-b</font></strong></pre>
<pre>Microsoft (R) Windows Debugger Version 6.11.0001.404 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows XP 2600 x86 compatible target at (Tue Sep  8 22:33:27.267 2009 (GMT-3)), ptr64 FALSE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y &lt;symbol_path&gt; argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntkrnlpa.exe -
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp_sp2_rtm.040803-2158
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x805531a0
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntkrnlpa.exe -
nt!DbgBreakPointWithStatus+0x4:
80526da8 cc              int     3
kd&gt; lm
start    end        module name
804d7000 806ce300   nt         (export symbols)       ntkrnlpa.exe
806cf000 806ef380   hal        (deferred)
f96f0000 f970a580   Mup        (deferred)
f970b000 f9737a80   NDIS       (deferred)
f9738000 f97c4480   Ntfs       (deferred)
f97c5000 f97db780   KSecDD     (deferred)
f97dc000 f97edf00   sr         (deferred)
f97ee000 f980c780   fltMgr     (deferred)
f980d000 f9824800   SCSIPORT   (deferred)
f9825000 f983c480   atapi      (deferred)
f983d000 f985bb80   ftdisk     (deferred)
f985c000 f986cd80   pci        (deferred)
f986d000 f989b000   ACPI       (deferred)
f999c000 f99a4d80   isapnp     (deferred)
f99ac000 f99b6500   MountMgr   (deferred)
f99bc000 f99c9000   VolSnap    (deferred)
f99cc000 f99d4e00   disk       (deferred)
f99dc000 f99e8200   CLASSPNP   (deferred)
f99ec000 f99f6580   agp440     (deferred)
f9c1c000 f9c22200   PCIIDEX    (deferred)
f9c24000 f9c28900   PartMgr    (deferred)
f9dac000 f9daf000   BOOTVID    (deferred)
f9db0000 f9db2480   compbatt   (deferred)
f9db4000 f9db7700   BATTC      (deferred)
f9db8000 f9dbab00   vmscsi     (deferred)
f9e9c000 f9e9db80   kdcom      (deferred)
f9e9e000 f9e9f100   WMILIB     (deferred)
f9ea0000 f9ea1600   intelide   (deferred)
kd&gt; .sympath
Symbol search path is: &lt;empty&gt;
Expanded Symbol search path is: &lt;empty&gt;
kd&gt; .symfix
kd&gt; .sympath
Symbol search path is: srv*
Expanded Symbol search path is: cache*C:\Tools\DbgTools\sym;SRV*http://msdl.microsoft.com/download/symbols
kd&gt; !process 0 0
**** NT ACTIVE PROCESS DUMP ****
NT symbols are incorrect, please fix symbols
kd&gt; .reload
Connected to Windows XP 2600 x86 compatible target at (Tue Sep  8 22:34:41.661 2009 (GMT-3)), ptr64 FALSE
Loading Kernel Symbols
...........................
Loading User Symbols

kd&gt; !process 0 0
**** NT ACTIVE PROCESS DUMP ****
NULL value in PsActiveProcess List<font color="#ff0000"> <strong><font color="#000000"> &lt;-- Nenhum processo por aqui</font></strong></font>
kd&gt; !thread0 0
No export thread0 found
kd&gt; !thread 0 0
00000000: Unable to get thread content<font color="#000000">s</font><font color="#000000"> <strong> &lt;-- Nenhuma thread também!</strong></font>
kd&gt; r
eax=00000001 ebx=80087000 ecx=80548c74 edx=80548c44 esi=80087000 edi=00000000
eip=80526da8 esp=80548c60 ebp=80548de8 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202
nt!RtlpBreakWithStatusInstruction:
80526da8 cc              int     3
kd&gt; k
ChildEBP RetAddr
80548c5c 80682baa nt!RtlpBreakWithStatusInstruction
80548de8 8068fd48 nt!ExpInitializeExecutive+0x350
80548e3c 8068d99b nt!KiInitializeKernel+0x3b2
00000000 00000000 nt!KiSystemStartup+0x2bf
kd&gt; kv
ChildEBP RetAddr  Args to Child
80548c5c 80682baa 00000001 80551920 00000000 nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0])
80548de8 8068fd48 00000000 80087000 8003fc00 nt!ExpInitializeExecutive+0x350 (FPO: [2,93,4])
80548e3c 8068d99b 80551b80 80551920 80549100 nt!KiInitializeKernel+0x3b2 (FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiSystemStartup+0x2bf</pre>
<p>Todos os módulos carregados antes dessa fase são os drivers que tiveram seu Start definido em zero no registro. Todos os programadores que desenvolvem esses drivers gostariam de um dia poder usar o WinDbg. Mas não podem. Quem inicia a comunicação serial com o depurador é o kernel, que só recebe o controle do ntldr depois que os drivers básicos foram carregados.</p>
<p>Brincadeira. É claro que esses programadores usam o WinDbg, usam <a href="http://www.driverentry.com.br/blog/2007/07/bug-em-meu-driver-de-boot-j-posso.html">até demais</a>. Mas só a partir desse ponto. Se algum problema evitar que o sistema chegue nessa fase, o desenvolvedor terá que usar métodos alternativos de depuração, como <a href="http://br.answers.yahoo.com/question/index?qid=20090203065437AAYWuPo">teste de mesa</a> (risos incontroláveis).</p>
<p>De qualquer forma, estamos aí. Agora podemos depurar a criação de qualquer thread, qualquer processo, o carregamento de qualquer módulo, e a chamada a qualquer função do kernel.</p>
<p>Para depurar a criação de qualquer thread: coloque um breakpoint na função <strong>PsCreateSystemThread</strong>.</p>
<pre>kd&gt; bp PsCreateSystemThread
kd&gt; bl
 0 e 805c732e     0001 (0001) nt!PsCreateSystemThread

kd&gt; g
Breakpoint 0 hit
nt!PsCreateSystemThread:
805c732e 8bff            mov     edi,edi
kd&gt; k
ChildEBP RetAddr
805499a8 8069c17e nt!PsCreateSystemThread
80549a4c 8069c419 nt!PspInitPhase0+0x3f0
<strong>80549a58 8068509c nt!PsInitSystem+0x33</strong>
80549be8 80691f28 nt!ExpInitializeExecutive+0x742
80549c3c 8068fa9f nt!KiInitializeKernel+0x3b2
00000000 00000000 nt!KiSystemStartup+0x2bf</pre>
<p>Para depurar a criação de qualquer processo: coloque um breakpoint na função <strong>PspCreateProcess</strong>, logo no começo. Será possível capturar a criação do processo System, o processo onde roda a primeira thread do kernel, que inicializa o resto dos componentes.</p>
<pre>kd&gt; bp PspCreateProcess
kd&gt; bl
 0 e 805c6a8c     0001 (0001) nt!PspCreateProcess

kd&gt; g
Breakpoint 0 hit
nt!PspCreateProcess:
805c6a8c 681c010000      push    11Ch
kd&gt; k
ChildEBP RetAddr
805499a0 8069c0dc nt!PspCreateProcess
<strong>80549a4c 8069c419 nt!PspInitPhase0+0x34e</strong>
80549a58 8068509c nt!PsInitSystem+0x33
80549be8 80691f28 nt!ExpInitializeExecutive+0x742
80549c3c 8068fa9f nt!KiInitializeKernel+0x3b2
00000000 00000000 nt!KiSystemStartup+0x2bf</pre>
<p>E não é lindo ver que, após a chamada ao Process Manager o processo REALMENTE foi criado e está na lista de processos?</p>
<pre>kd&gt; !process 0 0
**** NT ACTIVE PROCESS DUMP ****
TYPE mismatch for process object at 8055a0d0
kd&gt; gu
nt!PspInitPhase0+0x34e:
8069c0dc 85c0            test    eax,eax
kd&gt; !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 81bcc830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00319000  ObjectTable: e1000cc0  HandleCount:   1.
<strong>    Image: System Process</strong></pre>
<p>É nesse momento que percebemos que um processo, uma thread, um qualquer-coisa dentro do kernel não é nada mais nada menos que <strong>um item em uma lista</strong>. Quase tudo no kernel será um item numa lista com um monte de ponteiros referenciando outras estruturas. É isso que mantém a lógica e a coerência no sistema inteiro. Tudo isso é basicamente software, construído como castelos no ar.</p>
<p>O próximo processo a ser criado, logo após carregar todos os drivers, é o nosso amigo SMSS, o Gerenciador de Sessão, o primeiro pedacinho do iceberg que desponta no oceano. É ele que irá iniciar toda a "parte user-mode do kernel".</p>
<blockquote><p><em>Nota: Apesar de parecer contraditório, algumas partes do kernel são de fato implementadas em user mode. Os motivos podem variar, mas geralmente são maior segurança (código que não precisa rodar em um ring privilegiado) e desempenho (código que não precisa de muita prioridade).</em></p></blockquote>
<pre>Breakpoint 0 hit
nt!PspCreateProcess:
805c6a8c 681c010000      push    11Ch
kd&gt; kv
ChildEBP RetAddr  Args to Child
f9dc365c 805c73e1 f9dc3858 001f0fff f9dc37c0 nt!PspCreateProcess (FPO: [Non-Fpo])
f9dc36b0 805c745d f9dc3858 001f0fff f9dc37c0 nt!NtCreateProcessEx+0x77 (FPO: [Non-Fpo])
f9dc36dc 8053d638 f9dc3858 001f0fff f9dc37c0 nt!NtCreateProcess+0x3d (FPO: [Non-Fpo])
f9dc36dc 804fe155 f9dc3858 001f0fff f9dc37c0 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f9dc3704)
f9dc3774 8069caa3 f9dc3858 001f0fff f9dc37c0 nt!ZwCreateProcess+0x11 (FPO: [8,0,0])
f9dc3818 80686681 <strong>f9dc38b0</strong> 00000040 00040000 nt!RtlCreateUserProcess+0x125 (FPO: [Non-Fpo])
f9dc3dac 805c6160 80087000 00000000 00000000 nt!Phase1Initialization+0x1059 (FPO: [Non-Fpo])
f9dc3ddc 80541dd2 80685628 80087000 00000000 nt!PspSystemThreadStartup+0x34 (FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
kd&gt; !ustr <strong>f9dc38b0</strong>
<strong>String(58,520) at f9dc38b0: \SystemRoot\System32\smss.exe</strong>

kd&gt; gu
kd&gt; !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 81bcc830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00319000  ObjectTable: e1000cc0  HandleCount:  52.
    Image: System

PROCESS 81a2a430  SessionId: none  Cid: 0218    Peb: 7ffd6000  ParentCid: 0004
    DirBase: 08500020  ObjectTable: e1584818  HandleCount:   0.
<strong>    Image: smss.exe</strong></pre>
<p>Como podemos ver, isso é muito divertido e muito extenso. Poderíamos ir para qualquer lado da evolução do boot. Talvez em artigos futuros daremos uma olhada no processo de logon de um usuário, o que nos obrigaria a ter uma leve noção de como o Windows autentica e autoriza as pessoas. ou talvez daremos uma passadinha no sistema de escalonamento de threads do kernel, um assunto pra lá de complicado e esotérico.</p>
<blockquote><p><em>Nota: Eu pessoalmente recomendo acompanhar o processo de boot descrito por Russinovich e depurar passo-a-passo um boot de verdade. Serão horas e mais horas de puro conhecimento empírico catalogado em seu cérebro-depurador.</em></p></blockquote>
<p>Então até lá. Com licença que eu preciso ver a criação do System mais uma vez.</p>
<pre>.reboot</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/o-boot-no-windows-kernel/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
