2016-03-18

javascript: is Element really really visible?

/**
 * Is the element visible by the Eye?
 * @param {Element | jQuery} el - object to check. Either an Element or a jQuery selection.
 * @returns {object} True if it can be seen.
 */
function isElementVisible(el) {
    "use strict";
    if (!el) // Can't find? Can't see!
        return false;
    var v_element = (el instanceof jQuery) ? el : $(el);
    if (v_element.length === 0) // Still nothing to look for
        return false;
    return v_element[0].isSameNode(document.elementFromPoint((v_element.width() / 2) + v_element.offset().left, (v_element.height() / 2) + v_element.offset().top));
}

What happens here?

We are checking if the element at the given point (our element's middle) is the same element as returned by document.elementFromPoint: then we can see it. If a different one, then that foreign element overlays the one we are looking for.

2016-03-09

linux: fun: Detect debugger and interrupt conditionally

I wanted to place breakpoints to a binary written in C, so I don't have to type in all the breakpoints to gdb, and generally just to learn new tricks :-) Because it has no real life benefits...but it's fun!

For starters, I've found out that I can send a SIGTRAP multiple ways. The easier is to just raise it:
#include <signal.h>
raise(SIGTRAP); // or SIGINT if you also like to live dangerously
The funnier way is to emit it directly in asm:
__asm__("int $3");
// or
__asm__("int3");
To be honest, the latter is a software interrupt, not a signal, but has the same effect. The IA32 Book ("Intel® 64 and IA-32 Architectures Software Developer’s Manual, Chapter 6.4.4") says:
The INT 3 instruction explicitly calls the breakpoint exception (#BP) handler.
So I'm gonna stay with "does the same", as it is a deliberately tricky one.

But if you're not running through a debugger, it will leak to the kernel and that eventually stops your program (like, saying "Trace/BPT trap". BPT --> breakpoint, see?). We need to emit this signal conditionally, which leads us to the next problem: at any given time, are we debugged/traced or not?

Time to look up some anti-debug techniques.

The first idea that got me is to simply try to have the program to debug itself [terms and conditions apply], with PTRACE_TRACEME. The trick is that this call will fail if we are already debugged/traced. Then we can just flip a flag and have our signals protected with a condition.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // raise, SIG*
#include <errno.h> // errno
#include <string.h> // strerror

#include <sys/ptrace.h> // ptrace
#include <sys/types.h>

int has_dbg()
{
    long rc = ptrace(PTRACE_TRACEME, 0, 0, 0);
    if (rc < 0) {
        printf("traceme resulted in %ld, errno: %d, %s\n", rc, errno, strerror(errno));
        return 1;
    } else {
        return 0;
    }
}
Oopsie, there is a problem: you can't release TRACEME from the tracee, and while TRACEME is active, you cannot attach from the outside. While this anti debug technique is awesome for blocking out debuggers, we don't want this side effect. We have to release it, but we can't do it from here. So we have to do it somewhere else :-)

I've poked around with fork-and-traceme, but it's cumbersome. But I found an elegant solution on stackoverflow (where else): Just check /proc/self/status if TracerPid is zero or not. Genius.

Caveats: ps also reads /proc/* for status info so it must be pretty standard.

So our check looks like the following:
#include <stdio.h>
#include <stdlib.h> //atoi
#include <signal.h> // raise, SIG*
#include <string.h> // strstr, strerror
#include <fcntl.h> // open
#include <unistd.h> // read, close

int has_dbg()
{
    char buf[2048], *tracer_pid;
    int debugger_present = 0; // We say "no" if not found or error, as we are cowards.
    static const char TracerPid[] = "TracerPid:";
    ssize_t num_read;

    int status_fd = open("/proc/self/status", O_RDONLY);

    if (status_fd == -1)
        return 0;

    num_read = read(status_fd, buf, sizeof(buf));
    close(status_fd);

    if (num_read > 0)
    {
        buf[num_read] = 0;
        tracer_pid = strstr(buf, TracerPid); // Look for "TracerPid"
        if (tracer_pid)
            debugger_present = !!atoi(tracer_pid + sizeof(TracerPid) - 1); // parse an int, and bool-ify it.
    }

    return debugger_present;
}

int main(int argc, char **argv)
{
    if(has_dbg()) {
        printf("can has\n");
    } else {
        printf("no no\n");
    }

    return 0;
}
And the best part is, we can call this function at any time we want.

Now, we can do things like:
#define HALP do{if(has_dbg()){__asm__("int $3");}}while(0)

// ...

printf("foo\n");
if (3.14 >= 3.14)
{
    printf("bar\n");
    HALP;
    printf("baz\n");
}
printf("quux\n");
Isn't it fancy?

Note:

If you love to cut on characters you have to type, I suggest the raise version in the long run:
  • raise variant uses 20 + n*14 chars. (headers, you know)
  • asm variant uses n*17 chars.
Okay, just kidding.

2016-02-25

Note to self #2

When validating an XML against an XSD, make sure to use the correct XSD.
No matching global declaration available for the validation root

2016-02-24

hupquote #2

Igen ez is igaz, de van egy masik oldala is. Az egesz agile tema valahol annak besimerese, hogy a szoftverfejlesztes ido es eroforrasigenye egy bizonyos meret folott nem tervezheto.
-- http://hup.hu/szavazasok/20160222/nem_agile_fejlesztunk_mert?comments_per_page=9999#comment-1962685

2016-02-19

cpp: GLIBCXX suckage

So I'm working on a pretty old system, with a new GCC compiler installed. A boost based project I just received started babbling about /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./XYZ).
Wtf?

Turned out, the libstdc++.so.6.0.10 contains symbols up to GLIBCXX_3.4.10, but GCC 4.8.1 only links to newer ones.
How to check: strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX

Solution: I just downgraded to GCC 4.3.4 - so long, suckers!

bash: homemade timeout replacement

So I was young and reckless, and didn't know there is a command called timeout in coreutils. This is how I managed to do it:
#!/bin/sh
{
    ./time_consuming_binary -a param -a notherparam --pleaseblock
} &
CHILDPID=$!
# Kill it after 30 sec
sleep 30
kill -9 $CHILDPID 2>&1 /dev/null
How to check if it had to be killed or not? Measure the wall time of the execution :) I've used it in a Nagios service check, the thing it watched either returned under 5 sec or blocked indefinitely (thanks, NFS), hence the 30 secs.

2016-02-08

boost: Boost.FileSystem linking struggle

Struggling with boost? SSDDBS

If you already linked boost_filesystem and boost_system but still receive errors like boost/system/error_code.hpp:221: undefined reference to `boost::system::generic_category()', then you should add the following flags to your $(CPP) flags: -DBOOST_NO_CXX11_SCOPED_ENUMS -DBOOST_SYSTEM_NO_DEPRECATED

2016-02-05

Adventure Time Advice


Jake: You see this cup? This is literally my favorite cup.
* Jake throws the cup through the window *
Jake: Now it's gone forever. So it's not real and I don't care about it anymore.

2016-01-31

Some Hungarian laws #2

2012. évi C. törvény a Büntető Törvénykönyvről - II. FEJEZET - Területi és személyi hatály - 3. § (1) c)
3. § (1) A magyar büntető törvényt kell alkalmazni
a) a belföldön elkövetett bűncselekményre,
b) a Magyarország területén kívül tartózkodó magyar felségjelű úszólétesítményen vagy magyar felségjelű légi járművön elkövetett bűncselekményre,
c) a magyar állampolgár által külföldön elkövetett olyan cselekményre, amely a magyar törvény szerint bűncselekmény.

2016-01-20

music: synthwave/ outrun/ retroware playlist

  1. Carpenter Brut - FRA - playlist, bandcamp
  2. Perturbator - FRA - playlist, The Uncanny Valley, bandcamp
  3. Lazerhawk - USA (Austin, TX) - playlist, bandcamp
  4. Miami Nights 1984 - CAN (Victoria, BC) - playlist, bandcamp
  5. Mitch Murder - SWE (Stockholm) - playlist, Kung Fury OST, bandcamp
  6. Betamaxx - USA (Pittsburgh, PA) - playlist1, playlist2, bandcamp
  7. Power Glove - AUS (Melbourne) - playlist, Blood Dragon OST, bandcamp
  8. Vector Hold - USA (San Jose, CA) - playlist
  9. Timecop1983 - NL (Eindhoven) - playlist1, playlist2
  10. Waveshaper - SWE (Stockholm) - playlist, bandcamp
  11. Garth Knight - UK (Glasgow) - playlist1, playlist2, bandcamp
  12. Dynatron - DEN (Copenhagen) - playlist1, playlist2 
  13. Bourgeoisie - USA (Miami, FL) - playlist, bandcamp
  14. Mega Drive - USA (Dallas, TX) - playlist1, playlist2, playlist3, bandcamp
  15. Zombie Hyperdrive - GER (Halle) - track, bandcamp
...or start here: "Back To The 80's" Mix on YT

Disclaimer: Do not drive under the influence of these.