Big Fish Eat The Little Ones

Careful there little fish, getting what you want might be the last thing you should want…

Long story (not so) short:
This all started out with me taking the initiative to have the two shared ADSL lines of the office commune I’m part of replaced with a single high quality 100/100Mbit optical fiber based subscription.

Our office commune is housed in two apartments on the first floor that we’re letting from a housing cooperative (andelsboligforening in danish). And ten days prior to the fiber line installation, the chairman of this housing cooperative contacted me about him having noticed that there was fiber being dug into our street(!) and about him having secured a deal at a “lucrative” (but at that time undisclosed) price that we could be in on if we wanted to. I wrote him back that it was something we were already having installed and gave him my phone number and told him to call me if there was anything he’d like to know about what was going on. I also made the mistake of suggesting that if he was interested, I could probably sell him part of our Internet capacity at a lower price than the price of getting their own dedicated line.

The fiber company installed one cable with 12 fibers, of which we are using one, and since the chairman had expressed interest in getting a fiber installation for the housing cooperate, I thought the only decent thing to do would be to terminate the cable in a wiring closet in the basement so that others could have access to the remaining 11 optical fibers.
Our optical fiber was run through already existing cable trays up to the first floor where we had our fiber-router installed inside one of the apartments we’re letting. And all was good… For a few days.

I was contacted by the guy acting as the primary liaison between the office commune and the housing cooperative, that the chairman was going ballistic about us having installed something in the basement and using their cable trays without their prior written consent.
So after some difficulties of getting hold of the chairman (he claimed that he’d had to change phone numbers because of a job-change…) I talked with him on the phone for about half an hour.

I had the feeling that the conversion was going really well, as I was able to counter any claim he made, of which some where really ridiculous, with sound technical arguments, and clearly showed him that the installation was in fact to their advantage, as they now could get optical fiber based Internet at a reduced price because I had decided to pay a premium price for the initial installation to our address. However, it turned out he didn’t quite share my impression of how the conversation was going, as every time I refuted one of his claims he defaulted back to “but you didn’t get our prior written consent” and he abruptly ended the conversation by saying “this isn’t going anywhere, I’m going to talk with [the liaison guy] instead!”

Extortion at play

It’s a really nice Internet Connection you’ve gotten yourself there. It would be a real shame if I would have to force you to take it down…

This was the first very clear indication to me that he is trying to extort me for free Internet access.

Then the liaison guy talked with the chairman, and reported back to me that the chairman was now all smiles and sunshine and was going to contact the Internet Provider to find out what sort of advantageous deal the housing cooperative was eligible for.

Then he got angry again when he found out that the very reasonable price of 1130 danish krones (approx €152) for a unmetered optical fiber based 100/100 Mbit professional grade connection that he had already been given 5 days prior to contacting me, was already based on the fact that there was an existing fiber installation in the building (the one I accepted to fork out extra for).

So a few days later the liaison guy and I receive an e-mail that primarily stresses that there is no economic advantage for the housing cooperative in having the wiring closet (which he erroneously believes to be a fiber-router) in their basement, and that the hole through which the fiber-cable enters the basement (less than 2cm in diameter and filled with a cable) is increasing the basements exposure to moisture, which they’ve had troubles with in the past. This would clearly not have been a problem, had the same company made the installation on behalf of the housing cooperative… An installation he did seem very keen on only a few weeks earlier…

I’ve included the e-mail below, slightly censored, to give danish readers an impression of how annoying it is to deal with someone who clearly wants you to give him something, but is careful not to express what that is directly. It’s a real shame my “extortion-ese” is so poor that I’m unable to understand and give him what he wants…

Hej [liaison guy] og Daniel

Opstilling af udstyr og kabling i bygning:
Som nævnt i telefonen er jeg utilfreds med, at i har trukket kabler i vores kælder uden vores skriftelige tilladelse. Jeg går ud fra at jeres kabelføring har medført at der er lavet hul i vores væg/sokkel. Da vi har problemer med vand i kælderen, har vi ikke brug for yderligere problemer. I har opsat en boks med en Cisco ME3400 switch i kældergangen, som er koblet til lysnettet – og hvem skal betale for det?

Samarbejde:
Det var hele tiden min forståelse at i ønskede at samarbejde med os omkring etabelering af internet via [Internet Provider], men da i allerede har installeret udstyr og indgået aftaler med [Internet Provider], kommer man frem til en løsning, hvor der ikke er nogle fordele for os.
Switchen er leveret af [Internet Provider]. I følge [Internet Provider] kan denne switch ikke deles mellem os af kommercielle grunde; derfor skal der opsættes endnu en switch i kælderen, hvis andelshavere skal kobles på [Internet Provider]. Så ved denne løsning, er der ingen kommercielle fordele ved at beboere kobler sig på [Internet Provider].
Jeg vil nu tage kontakt til vores advokat for at høre hvordan vi skal håndtere denne sag.

Med venlig hilsen
[The Extortionist]

Now I no longer have any doubts that this is all about extortion. But [liaison guy] seems to be perfectly fine with that, pointing out that it’s all our fault for not getting the prior written consent (WTF?).

Initially I’m like, sure we’ll try to figure this out somehow, then it starts growing on my that I’m being coerced into doing something for free for someone who’s starting more and more to resemble the incarnation of a perfect asshole, and I realise that I at least have to put all his misunderstandings right in writing, because being enlightened on the technical intricacies of optical fiber network installations is clearly what this guy is after, right?

So I write him a lengthy e-mail where I basically point out that

a) You have already been offered high quality fiber Internet access at a reduced price because of us, so there is an economic advantage in this for you and

b) We could have asked to have the wiring closet in our apartment, but that would have meant that you would have been denied access to getting any fiber, surely that is not what you want
and

c) I’ll happily pay for the electricity used by the wiring closet out of my own pocket until the day when the co-operative housing decided to order their own fiber line from [Internet Provider]

Hej [The Extortionist],

Nu hvor jeg har undersøgt tingene nærmere og været tilbage og genlæst
vores korrespondence, er jeg blevet overbevist om at der er nogle helt
grundlæggende ting omkring forløbet som du har misforstået.

Det første du må forstå, er at den eneste grund til at [Internet Provider] lagde
fiber i [Office Street], er at jeg bestilte dem til at gøre det.
De kom ikke tilfældigvis forbi i et andet ærinde, hvor jeg så var så
heldig at lave en aftale med dem. Da jeg kontaktede dem befandt vi os
ganske vidst i den heldige situation hvor de alligevel var ved at at
projektere gravning i området i samme uge, hvilket gjorde at jeg kunne
få en aftale til en bedre pris end normalt, men det drejede sig stadig
om ca. 130 meter ekstra de skulle grave for at komme frem til os i
[Office Address].

Ud fra den forudsætning er det også klart at det tilbud på ca 1130
kroner eks. moms som du indhentede fra [Internet Provider] d. 20 august, var en
særligt gunstig pris som I kun kunne få, fordi jeg allerede havde
bundet mig til at få leveret en fibernetforbindelse til 1400 kroner
eks. moms per måned.
Til sammenligning tager TDC 2500 kroner eks. moms for en næsten lige
så god forbindelse (se deres priser her:
http://erhverv.tdc.dk/element.php?dogtag=e_prod_bb_bb )

Det er med andre ord fuldstændig forkert når du påstår at
andelsforeningen ikke har nogen fordel af at jeg har fået etableret en
fiberforbindelse til [Office Address], da det tilbud I fik på
fiberforbindelse var bedre end den aftale jeg havde fået, som jeg
allerede syntes var et kup.

Mht. til din utilfredshed med at fiberkablet er blevet termineret i et
krydsfelt kælderen, så er det meget nemt at argumentere for at både
[Internet Provider] og jeg handlede i god tro og med andelsforeningens interesse
for øje.

Jævnfør det at du indhentede et tilbud fra [Internet Provider] d. 20. august og
skrev til mig d. 25. august at I var interesserede i en
fiberforbindelse, gav det rigtig god mening at placere krydsfeltet i
kælderen torsdag d. 4 september. En placering hvorfra både vi og
andelsforeningen kan føre en fiber videre til en fiberswitche som den
vi nu har stående på 1. sal.

Kablet med alle 12 lysledere kunne sagtens være blevet terminer oppe
hos os på 1. sal, men så ville vi samtidig have udelukket jer fra at
kunne lave en seperat aftale med [Internet Provider]. Det er muligt at det stadig
kan lade sig gøre at ændre termineringen så alle 12 lysledere ender
oppe på 1. sal og derved udelukke jer fra at komme til at bruge dem,
men det burde heller ikke være i jeres interesse.

Mht. hvad der kan deles, så har du misforstået hvilken slags udstyr
der er blevet installeret i kælderen. Det der står i kælderen er et
fiber-krydsfelt, ikke en fiberswitch. Vi har en meget larmende og
strømforbrugende fiberswitch fra [Internet Provider] stående oppe hos os på 1. sal.
Omvendt bruger et fiber-krydsfelt, som jeg tidligere har forklaret dig
i telefonen, næsten ingen strøm.

Det er rigtig at I skal have jeres egen fiber-switch op at stå hvis I
skal have en seperat linie fra [Internet Provider], og det ville nok være en fordel
at opstille den i kælderen, da standard modellen larmer ganske meget.
Men du har fuldstændig misforstået at vi skulle have opstillet en
fiberswitch i jeres kælder. Det I har i kælderen er som sagt et
fiber-krydsfelt, og det har fået placeringen i kælderen for at give
jer mulighed for også at tilgå en fiberlinie hvis I måtte ønske at
lave en sådan aftale.

Indtil den dag hvor I måtte få jeres egen aftale med [Internet Provider], skal jeg
med fornøjelse betale hvad krydsfeltet måtte bruge af strøm fra
bygningens lysnet. Det kræver så at vi i fællesskab går ned til boksen
med en strøm-måler og bliver enige om hvilken effekt krydsfeltet
trækker. I vil så blive afregnet til gældende kWh pris.

To my big surprise [The Extortionist], simply disregards all my explanations and carefully constructed arguments with “I have my information from [Internet Provider] it’s their fault if there’s anything wrong with my assumptions, and the problem that you didn’t get our permission remains”. And more importantly he simply ignores my well founded claim that there is an advantage in this installation for them.

Hej Daniel

Tak for afklaringen.
Oplysningen om installationen, som jeg referere til, kommer alle fra [Internet Provider]. Så hvis de ikke er korrekte skyldes det [Internet Provider].

Problemet er stadig, at du har trukket kabler og installeret udstyr uden vores godkendelse.
Det har jeg gjort klart for [liaison guy] og dig flere gange. [liaison guy] har også erkendt at den manglende godkendelse, er en fejl.

Med venlig hilsen
[The Extortionist]

Facepalm

I guess it must be real easy being that stupid, or at least have the required lack of conscience to feign that level of stupidity at opportune moments…

Then it struck me that there is another co-operative housing in the next staircase to the right of us, which is at least the three times as large as the one we’re having problems with, so one could hope that they would find it well within their combined economic capacity to pay for their own Internet Access and also well beneath themselves to try to extort a small business such as myself into giving it to them for free.
We do share one wall with them, so maybe we could have our cable wiring moved to their basement and run a cable up to us via their staircase and one of their apartments.

So my reply to [The Extortionist] was simply:

“Do you mean to say that if I have the cabling re-laid outside your basement and cable trays, there will no longer a problem between us? Because I do believe that is something I can do.”

I’m still awaiting his reply on that suggestion, and honestly do not expect one. But getting into a cooperation with the larger co-operative housing next door is actually the better option for all parties.

  • [The Extortionist] gets a solution to the problem he’s drumming up (albeit I assume not the “solution” he’s aiming for)
  • I don’t have to deal with [The Extortionist]
  • [Internet Provider] gets an additional customer ([The Extortionist] isn’t going to buy from them as they cannot sell their high quality services at a price that is lower than what they’re already paying to another ADSL based ISP)
  • The co-operative housing next door gets high quality Internet at a very affordable price (and every bit of technical guidance I can give them).

So moving the fiber installation one address down the street is the option I’ll be pursuing going forwards with this mess.

But getting back to the headline of this post. How many of you would consider it a good idea to coerce  yourself  into getting free Internet access through somebody else’s network? I mean, where is the good sense in insisting on sending all your Internet traffic through a network controlled by a guy that you just pissed off in a big way?

Don't fuck with the smiling man

Don’t fuck with me bro!

I have 5 global IP addresses that came with the subscription, and I wouldn’t stop at using one of those IP’s to expose the computer of [The Extortionist] directly the Internet. No actually I’d be more than happy to spend a couple of days setting up a “Man In The Middle As A Service” directed solely at his computer as a big “thank you” to him for being such a swell and pleasant guy to deal with, and I would even put the additional effort into the endeavour of  informing the kind people in the shadier parts of the Internet about the situation and provide them with the attack vector for a perfect opportunity to destroy another life completely, for fun and profit.

How come that he’s actively striving for putting his personal information at my mercy? The way in which he seems so oblivious to this risk, reminds me of when my daughter, who’s turning five in a couple of weeks, tripped, fell and knocked out one of her teeth a couple of weeks ago. She handled it really well I was told, and only cried a little just after it happened, and when I got to the kindergarten about 15 minutes later, she seemed poised and was ready for me to take her to the dentist. However she did say “I didn’t know something like this could happen to children”, and I commend myself for not replying with “don’t worry sweetheart, a lot worse happens to other children every day” as my own father surely would have done ;)
And maybe it’s the same with [The Extortionist], he simply doesn’t know about the monster that lurk in the darkest and seediest parts of  Internet and what they routinely do to small fish like him, when given but half a chance.
I will of course not stoop to that level, and my prefered course of action is, as stated above, to work my way around him. But the thought of someone doing their best/worst and putting effort into trying to force me into routing their personal Internet traffic is pretty hilarious when one considers the vast opportunity for malice that opens up for on my part.

[To Be Continued…]

I’m getting ready for my first Ludum Dare game-jam, which I intentionally will refrain from calling a competition, as that would imply that I believe there is a chance of winning, which for me at this point would be missing the point.

Time Flies...

Time Flies…

Anyway, one of the things I noticed is that there is a tradition for making timelapse videos of the 48 hour creation process, and that there is a program called “Chronolapse” for making said videos which works in windows and linux, but apparently not OS X, which I intend to use for the competition. So building on information from this post on the LD website I’ve made a bash script which handles both continuously capturing the screenshots at preset intervals and putting them together in a timelapse video with ffmpeg.

The script as can be seen below is still a little hands on, but I’m not going to put more time into it at this time.
Notice also that adapting this script to work with linux should be as easy as finding a suitable replacement for the OS X screencapture command the script currently uses. Adaptation to windows should also be possible through something like CYGWIN given that a CLI screencapture program exists for that platform.

And to make it all a little more meta, here is a video of me making the script and writing this blog-post:

And without further ado is the script in all its syntax highlighted glory:

#!/usr/bin/env sh

# seconds between image captures
CAPTURE_RATE=30

#number of monitors to capture
NUM_SCREENS=2

capture_loop (){

    scrns_string () {
        local ti=0
        local outp=""

        while [ $ti -lt ${NUM_SCREENS} ]
        do
            outp="${outp} ${1}_m${ti}.png"
            (( ti++ ))
        done
        echo $outp
    }

    #fast forwards to largest numbered dump file in PWD
    i=0

    PREVIOUS=`ls  *_merged.png`
    for fn in $PREVIOUS
    do
        if [ ! -f "${i}_merged.png" ]
        then
            echo "${i}_merged.png"
            break
        fi
            (( i++ ))
    done

    echo "numbering from ${i}"

    while true ;
        do
            echo `date`‘ Capturing screenshot...’
            # IMGNAMES="${i}_m1.png ${i}_m2.png"
            IMGNAMES=$(scrns_string $i)
            # run three commands as one in the background to counter drifting
            screencapture -C -x ${IMGNAMES} && \
            `convert ${IMGNAMES} +append ${i}_merged.png` && \
            `rm ${IMGNAMES}` &
            sleep $CAPTURE_RATE
            (( i++ ))
    done
}

#combine png images in PWD to movie
make_video (){

    sequentialize

    SEPTS=""
    if [ -z "$1"]
        then
        SEPTS="5.0"
    else
        SEPTS=$1
    fi

    echo "setpts=${SEPTS}*PTS"

    ffmpeg -start_number 000001 -i seqtmp_%06d.png -vcodec libx264 -r 30 -b:v 5000k \
         -filter:v "setpts=${SEPTS}*PTS"  timelapse.mp4
    # -s 3840x1200

    #remove symlinks
    rm seqtmp_*.png
}

# make sorted soft links to images in
# sequential continous order
sequentialize (){
    c=1
    for i in `ls *_merged.png | sort -n`
    do
       printf -v NN 'seqtmp_%06d.png' "$c"
       ln -sf ${i} ${NN}
       (( c++ ))
    done
}

# if no arguments given,
if [ -z "$1" ]
then
   capture_loop
elif [ "$1" == "--sequentialize" -o "$1" == "-S" ]
then
    sequentialize
elif [ "$1" == "--video" -o "$1" == "-V" ]
then
    echo "making video"
    if [ -z "$2" ]
    then
        make_video
    else
        make_video $2
    fi
else

    echo "Unknown argument: $1"
    echo "Usage $0 [-combine ouputname.mp4]"
fi

I'm backAfter being off the grid since some time in august 2013. The hiatus probably has done all sorts of wonders to my already at that time not too impressive google rank :-p

I could of course have prioritised the time to transfer this blog to a new server within a few days of it going off-line, but I’ve been feeling extremely busy in the interrim and there was very little that I felt the need to communicate through this medium. By which I’m of course implying that there is stuff that I want to publicise within the next fortnight or so. So stay tuned for hitherto unseen levels of geekery*.

*Besides from those three posts on assembly control flow annotation which aren’t going to be surpassed in the immediate future :-p

Line chaser

 


I got a comment to my initial post about ASM ctrl-flow visualisation which ends with the following remark:

The code runs into problems when faced with code with very large numbers of jumps in, such as from a large ‘switch’ statement or just where there’s rather a lot of conditions being checked…

I’m guessing that this is about the same issue I’ve noticed myself, that some functions with a lot of jump instructions, like say the free function in dlmalloc, results in an arrow-gutter of around 80 characters run through my initial script.

The reason for this is that I chose to reserve one column for each jump instruction within a function. This was simpler to write and has some readability benefits IMO but can also lead to arrow-gutters that are much wider than they need to be.

So this compact visualiser reuses columns that become available after arriving at the jump origin or destination. The example below only saves 5 columns compared to the less frugal script, but the previously mentioned free function goes down from using 80 columns for arrows to a mere 18.

0804debc <img_text>:
          804debc:	55                   	push   ebp
          804debd:	89 e5                	mov    ebp,esp
          804debf:	53                   	push   ebx
          804dec0:	83 ec 34             	sub    esp,0x34
          804dec3:	8b 45 0c             	mov    eax,[ebp+0xc]
          804dec6:	8b 00                	mov    eax,[eax]
          804dec8:	85 c0                	test   eax,eax
       ,--804deca:	74 3c                	je     804df08 
       |  804decc:	8b 45 0c             	mov    eax,[ebp+0xc]
       |  804decf:	83 c0 04             	add    eax,0x4
       |  804ded2:	8b 00                	mov    eax,[eax]
       |  804ded4:	85 c0                	test   eax,eax
      ,|--804ded6:	74 30                	je     804df08 
      ||  804ded8:	8b 45 0c             	mov    eax,[ebp+0xc]
      ||  804dedb:	83 c0 08             	add    eax,0x8
      ||  804dede:	8b 00                	mov    eax,[eax]
      ||  804dee0:	85 c0                	test   eax,eax
     ,||--804dee2:	74 24                	je     804df08 
     |||  804dee4:	8b 45 0c             	mov    eax,[ebp+0xc]
     |||  804dee7:	83 c0 0c             	add    eax,0xc
     |||  804deea:	8b 00                	mov    eax,[eax]
     |||  804deec:	85 c0                	test   eax,eax
    ,|||--804deee:	74 18                	je     804df08 
    ||||  804def0:	8b 45 0c             	mov    eax,[ebp+0xc]
    ||||  804def3:	83 c0 10             	add    eax,0x10
    ||||  804def6:	8b 00                	mov    eax,[eax]
    ||||  804def8:	85 c0                	test   eax,eax
   ,||||--804defa:	74 0c                	je     804df08 
   |||||  804defc:	8b 45 0c             	mov    eax,[ebp+0xc]
   |||||  804deff:	83 c0 14             	add    eax,0x14
   |||||  804df02:	8b 00                	mov    eax,[eax]
   |||||  804df04:	85 c0                	test   eax,eax
  ,|||||--804df06:	75 2f                	jne    804df37 
  |'''''->804df08:	a1 40 0b 05 08       	mov    eax,ds:0x8050b40
  |       804df0d:	89 44 24 0c          	mov    [esp+0xc],eax
  |       804df11:	c7 44 24 08 1e 00 00 	mov    [esp+0x8],0x1e
  |       804df18:	00 
  |       804df19:	c7 44 24 04 01 00 00 	mov    [esp+0x4],0x1
  |       804df20:	00 
  |       804df21:	c7 04 24 e0 f0 04 08 	mov    [esp],0x804f0e0
  |       804df28:	e8 b3 aa ff ff       	call   80489e0
  |       804df2d:	b8 ff ff ff ff       	mov    eax,0xffffffff
  |    ,--804df32:	e9 79 01 00 00       	jmp    804e0b0 
  '----|->804df37:	8b 45 0c             	mov    eax,[ebp+0xc]
       |  804df3a:	8b 00                	mov    eax,[eax]
       |  804df3c:	89 04 24             	mov    [esp],eax
<snip>
       |  804dfe2:	8b 45 dc             	mov    eax,[ebp-0x24]
       |  804dfe5:	89 45 e8             	mov    [ebp-0x18],eax
      ,|--804dfe8:	e9 a5 00 00 00       	jmp    804e092 
     ,||->804dfed:	c7 45 f4 00 00 00 00 	mov    [ebp-0xc],0x0
    ,|||--804dff4:	e9 87 00 00 00       	jmp    804e080 
   ,||||->804dff9:	8b 45 e8             	mov    eax,[ebp-0x18]
   |||||  804dffc:	0f b6 00             	movzx  eax,[eax]
   |||||  804dfff:	0f b6 d0             	movzx  edx,al
<snip>
   |||||  804e01b:	c7 45 f0 00 00 00 00 	mov    [ebp-0x10],0x0
  ,|||||--804e022:	eb 52                	jmp    804e076 
 ,||||||->804e024:	0f b7 45 e6          	movzx  eax,[ebp-0x1a]
 |||||||  804e028:	83 e0 01             	and    eax,0x1
 |||||||  804e02b:	85 c0                	test   eax,eax
,|||||||--804e02d:	74 3f                	je     804e06e 
||||||||  804e02f:	8b 45 08             	mov    eax,[ebp+0x8]
||||||||  804e032:	8b 00                	mov    eax,[eax]
<snip>
||||||||  804e067:	0f b6 40 02          	movzx  eax,[eax+0x2]
||||||||  804e06b:	88 42 02             	mov    [edx+0x2],al
'|||||||->804e06e:	66 d1 6d e6          	shr    [ebp-0x1a],1
 |||||||  804e072:	83 45 f0 01          	add    [ebp-0x10],0x1
 |'|||||->804e076:	83 7d f0 0b          	cmp    [ebp-0x10],0xb
 '-|||||--804e07a:	7e a8                	jle    804e024 
   |||||  804e07c:	83 45 f4 01          	add    [ebp-0xc],0x1
   |'|||->804e080:	83 7d f4 05          	cmp    [ebp-0xc],0x5
   '-|||--804e084:	0f 8e 6f ff ff ff    	jle    804dff9 
     |||  804e08a:	83 45 e8 01          	add    [ebp-0x18],0x1
     |||  804e08e:	83 45 ec 06          	add    [ebp-0x14],0x6
     |'|->804e092:	8b 45 e8             	mov    eax,[ebp-0x18]
     | |  804e095:	0f b6 00             	movzx  eax,[eax]
     | |  804e098:	84 c0                	test   al,al
     '-|--804e09a:	0f 85 4d ff ff ff    	jne    804dfed 
       |  804e0a0:	8b 45 dc             	mov    eax,[ebp-0x24]
       |  804e0a3:	89 04 24             	mov    [esp],eax
       |  804e0a6:	e8 f3 e2 ff ff       	call   804c39e &lt;free>
       |  804e0ab:	b8 00 00 00 00       	mov    eax,0x0
       '->804e0b0:	83 c4 34             	add    esp,0x34
          804e0b3:	5b                   	pop    ebx
          804e0b4:	5d                   	pop    ebp
          804e0b5:	c3                   	ret
Me getting a lot hits from reddit.com/r/programming

Me getting a lot hits from reddit.com/r/programming

Yesterday I wrote about a small script that visualizes control flow in ASM dumps with arrows and when a friend of mine posted it in reddit.com/r/programming I suddenly got a lot more traffic than usual and a bit of useful feedback that helped me improve the robustness and applicability of the script considerably.

This morning I noticed that the I’d also been getting a few referrer hits from this unlikely source http://llvm.org/bugs/show_bug.cgi?id=16297.

Reading that “request for feature” got me thinking that it ought to be dead easy to modify the existing script to also handle disassemblies from llvm-objdump.

An example of the result can be seen below.

     80486cb:	55                    	push	EBP
     80486cc:	89 e5                 	mov	EBP, ESP
     80486ce:	53                    	push	EBX
     80486cf:	83 ec 10              	sub	ESP, 16
     80486d2:	c7 45 f8 00 00 00 00  	mov	[EBP - 8], 0
 ,---80486d9:	eb 29                 	jmp	41
 |,->80486db:	8b 45 f8              	mov	EAX, [EBP - 8]
 ||  80486de:	8b 55 08              	mov	EDX, [EBP + 8]
 ||  80486e1:	8d 0c 02              	lea	ECX, [EDX + EAX]
 ||  80486e4:	8b 1d 4c a0 04 08     	mov	EBX, [134520908]
 ||  80486ea:	a1 54 a0 04 08        	mov	EAX, 134520916
 ||  80486ef:	89 c2                 	mov	EDX, EAX
 ||  80486f1:	01 da                 	add	EDX, EBX
 ||  80486f3:	0f b6 12              	movzx	EDX, BYTE PTR [EDX]
 ||  80486f6:	88 11                 	mov	BYTE PTR [ECX], DL
 ||  80486f8:	83 45 f8 01           	add	[EBP - 8], 1
 ||  80486fc:	83 c0 01              	add	EAX, 1
 ||  80486ff:	a3 54 a0 04 08        	mov	134520916, EAX
 '|->8048704:	8b 15 54 a0 04 08     	mov	EDX, [134520916]
  |  804870a:	a1 50 a0 04 08        	mov	EAX, 134520912
  |  804870f:	39 c2                 	cmp	EDX, EAX
,-|--8048711:	7d 14                 	jge	20
| |  8048713:	8b 15 4c a0 04 08     	mov	EDX, [134520908]
| |  8048719:	a1 54 a0 04 08        	mov	EAX, 134520916
| |  804871e:	01 d0                 	add	EAX, EDX
| |  8048720:	0f b6 00              	movzx	EAX, BYTE PTR [EAX]
| |  8048723:	3c 0a                 	cmp	AL, 10
| '--8048725:	75 b4                 	jne	-76
'--->8048727:	a1 54 a0 04 08        	mov	EAX, 134520916
     804872c:	83 c0 01              	add	EAX, 1
     804872f:	a3 54 a0 04 08        	mov	134520916, EAX
     8048734:	8b 45 f8              	mov	EAX, [EBP - 8]
     8048737:	83 c4 10              	add	ESP, 16
     804873a:	5b                    	pop	EBX
     804873b:	5d                    	pop	EBP
     804873c:	c3                    	ret

What made this version of the script a bit trickier to make was that where the classical objdump is kind enough to translate the target address for jump instructions to one of the relative offsets seen in the first column (ie. 80486db), llvm-objdump only does a litteral translation of the instruction name followed by the relative offset in bytes as a signed integer.

And with the x86 architectures notorious variable instruction length, finding the target address isn’t just a matter of counting the offset divided by instruction size as number of lines as it would be in a fixed length instruction set, but rather a matter of counting every byte on the way there. A slight added complication to this calculation is that the offset to start counting from is that of the instruction following the jump instruction.

If I had to work with assembly output like that, I would be begging for something like the sort of annotation this script provides ;)

The llvm version of the script is available for downlad here, and I assume that a diff between that and the vanilla objdump version would make an excellent starting point for anyone wanting to adapt the script to some other disassembly dialect.

Angelina Jolie doing 'sexy movie hacking' in 'Hackers'

Angelina Jolie doing ‘sexy movie hacking’ in ‘Hackers’

UPDATE: Since my initial post I’ve updated the code a couple of times to better support 64bit linux binaries and also objdumps of windows binaries. Let me know if you run into som sort of disassembly output from objdump that returns the input unaltered and I’ll see if I can make it work.

UPDATE 2: I’ve made a variant of this script for disassemblies from llvm-objdump. Read all about it.

UPDATE 3: Fixed some missing instructions and instruction synonyms. I’ve also added descriptions of the given jump instruction at the end of the line realising that trying to keep line lengths within 80 columns is a lost cause with this script ;)

I’m currently following a course on “Proactive Computer Security”, which, if you accept the fact that computers are the closest equivalent we’ve got to magic, equates to a “Defence Against The Dark Arts” class, and based on the same credo that one should familiarize oneself with how to attack in order to better defend.

Hacking of computer programs typically involves feeding that program an input that it wasn’t designed to handle properly, resulting in the attacker getting control or gaining information that she wasn’t supposed to.

So in this particular course we’ve been doing a lot of reverse engineering on disassembled programs in order to find weaknesses in their input handling.

A function handling an input of unknown length n bytes will typically have a loop that keeps running until a certain condition is met. Like in the following example where the instruction at 0x08048725 keeps jumping back to the instruction at 0x080486d9 if the latest character read from the input is not a newline. Notice also the jump at 0x08048711 that will jump past the test for newline if the end of the input has been reached.

080486cb <get_line>:
     80486cb:	55                   	push   ebp
     80486cc:	89 e5                	mov    ebp,esp
     80486ce:	53                   	push   ebx
     80486cf:	83 ec 10             	sub    esp,0x10
     80486d2:	c7 45 f8 00 00 00 00 	mov    [ebp-0x8],0x0
 ,---80486d9:	eb 29                	jmp    8048704 <get_line+0x39>
 |,->80486db:	8b 45 f8             	mov    eax,[ebp-0x8]
 ||  80486de:	8b 55 08             	mov    edx,[ebp+0x8]
 ||  80486e1:	8d 0c 02             	lea    ecx,[edx+eax*1]
 ||  80486e4:	8b 1d 4c a0 04 08    	mov    ebx,ds:0x804a04c
 ||  80486ea:	a1 54 a0 04 08       	mov    eax,ds:0x804a054
 ||  80486ef:	89 c2                	mov    edx,eax
 ||  80486f1:	01 da                	add    edx,ebx
 ||  80486f3:	0f b6 12             	movzx  edx,BYTE PTR [edx]
 ||  80486f6:	88 11                	mov    BYTE PTR [ecx],dl
 ||  80486f8:	83 45 f8 01          	add    [ebp-0x8],0x1
 ||  80486fc:	83 c0 01             	add    eax,0x1
 ||  80486ff:	a3 54 a0 04 08       	mov    ds:0x804a054,eax
 '|->8048704:	8b 15 54 a0 04 08    	mov    edx,ds:0x804a054
  |  804870a:	a1 50 a0 04 08       	mov    eax,ds:0x804a050
  |  804870f:	39 c2                	cmp    edx,eax
,-|--8048711:	7d 14                	jge    8048727 <get_line+0x5c>
| |  8048713:	8b 15 4c a0 04 08    	mov    edx,ds:0x804a04c
| |  8048719:	a1 54 a0 04 08       	mov    eax,ds:0x804a054
| |  804871e:	01 d0                	add    eax,edx
| |  8048720:	0f b6 00             	movzx  eax,BYTE PTR [eax]
| |  8048723:	3c 0a                	cmp    al,0xa
| '--8048725:	75 b4                	jne    80486db <get_line+0x10>
'--->8048727:	a1 54 a0 04 08       	mov    eax,ds:0x804a054
     804872c:	83 c0 01             	add    eax,0x1
     804872f:	a3 54 a0 04 08       	mov    ds:0x804a054,eax
     8048734:	8b 45 f8             	mov    eax,[ebp-0x8]
     8048737:	83 c4 10             	add    esp,0x10
     804873a:	5b                   	pop    ebx
     804873b:	5d                   	pop    ebp
     804873c:	c3                   	ret    

Now imagine following the above control flow without the arrows, which objdump, my disassembler of choice does, not provide for some reason.

Ida Pro Control Flow View

Ida Pro Control Flow View

Having these arrows in the assembly makes it both easier to identify sections of the code with a lot of control flow and perhaps more importantly faster to deduce the logic in said section.

Both the free reverse engineering framework radare and the rather costly IDA Pro suite does this already with a more graph like layout, but I believe my approach has qualities that they lack, in being so unobtrusive, simple and without other requirements than a python installation and the objdump program.

My arrow-annotating python code follows below, but people who expect to run it should probably download the file directly as the syntax highlighter tends to mangle the code enough to confuse the python intepreter.

#!/usr/bin/env python
# encoding: utf-8
"""
asm_jmps.py
Created by Daniel Fairchild on 2013-06-10.
Usage (in shell):
  objdump -M intel -d  target.bin | ./asm_jmps.py
License:
  I'd appreciate a comment at: http://blog.fairchild.dk/?p=633
  if you find the following usefull. That'll be all.
"""
import sys
import re

JMPS = { #define jumps, synomyms on same line
'ja':'if above', 'jnbe':'if not below or equal',
'jae':'if above or equal','jnb':'if not below','jnc':'if not carry',
'jb':'if below', 'jnae':'if not above or equal', 'jc':'if carry',
'jbe':'if below or equal', 'jna':'if not above',
'jcxz':'if cx register is 0', 'jecxz':'if cx register is 0',
'je':'if equal', 'jz':'if zero',
'jg':'if greater', 'jnle':'if not less or equal',
'jge':'if greater or equal',
'jl':'if less', 'jnge':'if not greater or equal',
'jle':'if less or equal', 'jnl':'if not less',
'jmp':'unconditional',
'jne':'if not equal', 'jnz':'if not zero',
'jng':'if not greater',
'jno':'if not overflow',
'jnp':'if not parity', 'jpo':'if parity odd',
'jns':'if not sign',
'jo':'if overflow',
'jp':'if parity', 'jpe':'if parity even',
'js':'if sign'}

fcl = re.compile(" +([\da-f]+)\:")
fjre=re.compile("".join([
            " +([\da-f]+)\:\\t.*(",
            "".join(map(lambda x: x+"|", JMPS))[:-1],
            ")\s+\*?0?x?([\da-f]+)"]))

def j_line(ln, ljmps):
  jl = len(ljmps)
  outl = [" "]*(jl+2)
  jdesc=""
  for i in range(jl):
    if ljmps[i][0] == ln: #jmp from
      outl[-(jl-i+2):] = ["-"]*(jl-i+2)
      outl[i] = "," if ljmps[i][0] < ljmps[i][1] else "\'"
      jdesc = "; jump %s" % ljmps[i][2]
    if ljmps[i][1] == ln: #jmp to
      outl[-(jl-i+1):] = ["-"]*(jl-i+1)
      outl[-1] = ">"
      outl[i] = "," if ljmps[i][0] > ljmps[i][1] else "\'"
    if ljmps[i][0] < ln and ljmps[i][1] > ln:
      outl[i] = "|"
    elif ljmps[i][0] > ln and ljmps[i][1] < ln:
      outl[i] = "|"
  return ("".join(outl),jdesc)

def drw_jmps(all_lines, fun_lines):
  ljmps = []
  for cl in fun_lines:
    m = fjre.match(all_lines[fun_lines[cl]])
    if m != None:
      if fun_lines.has_key(m.group(3)):
        ljmps.append((fun_lines[cl], fun_lines[m.group(3)],JMPS[m.group(2)]))
  #the following sorting bands same endpoints together
  ljmps = sorted(ljmps, key=lambda x: -x[1])
  for cl in sorted(fun_lines, key=lambda x: int(x,16)):
    jlr = j_line(fun_lines[cl],ljmps)
    all_lines[fun_lines[cl]]="".join([
                    jlr[0],
                    all_lines[fun_lines[cl]][:-1].lstrip(),jlr[1],
                    "\n"])

if __name__ == "__main__":
  #read lines from stdin
  nasml = sys.stdin.readlines()
  #make a dictionary of asm lines
  asm_lines = {}
  for i in range(len(nasml)):
    m = fcl.match(nasml[i])
    if m != None:
      asm_lines[m.group(1)] = i
    if nasml[i] == "\n" or "\tret " in nasml[i]:
      drw_jmps(nasml, asm_lines)
      asm_lines = {}
      fun_decl_lines = {}
  print "".join(nasml)
Lying About Cake Since 2007

The above image was kindly “borrowed” from this guy on DeviantArt

So Guillermo del Toro upcoming “Pacific Rim” has worlds colliding in more ways than one.

As anyone who has enjoyed the videogame Portal or its sequel will instantly recognize 46 seconds into this trailer, he has simply hired Ellen Mclain, who did such an excellent job of bringing the primary antagonist of the Portal games GlaDOS to life, to voice (wait for it…) an AI in the movie.

It’s even official in the sense that Guillermo del Toro even asked the videogame company Valve for permission to use the very distinct GlaDOS voice in his movie.

While I’m not one to complain about such a minor peculiarity, it’s Tinseltowns money after all and del Toro can do with it whatever they allow him to, hearing the super distinct GlaDOS voice transposed to a completely different setting and possibly even away from the antagonistic role we’ve come to associate her with really weirded me out, effecting in considerable distancing.

At the risk of coming off like an angry old man, I think it would be fair to assess that we’re pretty far away from the Auteur territory here and much closer to a meme-motivated-cross-pollinating-instant-gratification-oriented-entertainment-industrial-complex.

And if I’m not too completely mistaken it could easily serve as an example of the “triteness and shallowness resulting from the instantaneous, direct, and superficial participation in culture made possible by the internet, mobile phones, interactive television and similar means”, of postpost-modernism or  pseudo-modernism as described in the Wikipedia article from which i totally copied the previous quotation (see what I did there? ;)).

Anyway go have a gander at the trailer below if the above has in any way piqued your interest:

What The FileReadingExceptionIf you’re a programmer, or even just a bro-grammer, check this comment on the official .NET documentation out:

Offset and position parameters wrong in intellisense
Its *really* annoying when the Intellisense documentation is wrong when you are coding … it has been a frustrating exercise to figure this out. As a previous poster mentioned, the Intellisense doco for the offset and position parameters are swapped around. The parameter descriptions as shown on this page are correct.
[Source]

.NET intellisense pulling a dick move

Screencap of the “sligtly” misleading intellisense description from VS2010.

And let me just add that I would only stumble upon comedy gold like this after having had the most inexplicable out-of-bounds exception ever. Here is some simplified code that will throw an out-of-bounds exception on the 2nd read when reading from a file of 8 bytes or more:

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KeyValueBase.Interfaces;
using System.IO;
using System.IO.MemoryMappedFiles;

public class SomeClassName
{
	public void Init(String indexfile)
	{
		uint[] keypair = new uint[4];
		var mmName = Path.GetFileName(indexfile);
		using (var mStream = new FileStream(indexfile, FileMode.Open)){
			using (var mmf = MemoryMappedFile.CreateFromFile(
				mStream,
				mmName,
				mStream.Length, MemoryMappedFileAccess.Read, null,
				HandleInheritability.None, false)){

				using (var a = mmf.CreateViewAccessor(
						0, mStream.Length,
						MemoryMappedFileAccess.Read)){
					for (int i=0; i<mStream.Length; i+=2*sizeof(uint)){
						/* The wrongly documented function that leads
						 * to the most inexplicable out-of-bounds 
						 * exception.
						 * The following line is well behaved */
						a.ReadArray<UInt32>(i, keypair, 0, 4);
						/* This line on the contrary does something 
						 * "funny" with your program, try it! */
						// a.ReadArray<UInt32>(0, keypair, i, 4);
					}
				}
			}
		}
	}
}

I would of course be the last to want to generate negative prejudice towards the entire subspecies of .NET dependent bro-grammers, but I think it is fair to assume that this error would have been patched a long time ago if they in general were more prone to and proficient in dealing with binary data ;)

Extracting vectors from pdf files is surprisingly easy with Inkscape, once you’ve figured out the steps. I’ve made a brief graphical vector-extraction-guide in my notes-stream: Extract Vector Graphics From PDF Files With Inkscape – Imperfect Notes.

Fiasco Rocket

A guide for compiling a modified version of linux-2.6 to run paravirtualized inside the the L4Re is now to be found in my separate notes blog. Enjoy.

Getting L⁴Linux up and running – Imperfect Notes.

About this blog

The name is inspired by the saying: "perfection is the bane of all good things".
Read more