Monday, 19 July 2021
|
Écrit par
Grégory Soutadé

While developping the reverse of Adobe's library libRMSDK.so, I needed a script to find all dependencies of this library and dependencies of dependencies. All of them must be copied into one folder in order to be packaged. So I wrote this script that parses recursively objdump's ouput. Here is the code :

#!/bin/bash

# Copyright Grégory Soutadé

# This is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with iwla.  If not, see <http://www.gnu.org/licenses/>.
#


#
# Find all dependant shared libraries of a target (using objdump) and copy them into a directory
#


# Options
TARGET=""
OUTPUT=""
ROOT_LIB_DIRECTORY=""
OBJDUMP=objdump
VERBOSE=0
EXIT_ON_ERROR=0
QUIET_NOT_FOUND=0
CLEAN_BEFORE_START=0
COPY_TARGET=0

function debug()
{
    if [ $VERBOSE -eq 1 ] ; then
    echo -e "$1"
    fi
}

function copy()
{
    target=$1
    symlink_name=$2

    if [ ! -e ${target} ] ; then
    debug "${target} not found"
    return
    fi

    debug "cp --no-dereference ${target} ${OUTPUT}"
    cp --no-dereference ${target} ${OUTPUT}

    if [ ! $? -eq 0 ] ; then
    [ ${EXIT_ON_ERROR} -eq 1 ] && exit 1
    return
    fi

    if [ ! -z "${symlink_name}" ] ; then
    echo ln -s `basename ${target}` ${OUTPUT}/${symlink_name}
    ln -s `basename ${target}` ${OUTPUT}/${symlink_name}
    fi

    # Symlink ? Copy target file
    if [ -L ${target} ] ; then
    copy `readlink -e ${target}`
    fi
}

nb_tabs=0
function find_lib()
{
    target="$1"

    if [ ! -e ${target} ] ; then
    debug "${target} not found"
    return
    fi

    nb_tabs=$((${nb_tabs}+1))
    local tabs=""
    for i in `seq 1 ${nb_tabs}`; do
    tabs="${tabs}  "
    done

    dependencies=`${OBJDUMP} -p ${target}|grep NEEDED|sed "s/ \+/ /g"|cut -d' ' -f3`
    for dependency in ${dependencies} ; do
    symlink_name=""
    echo -e "${tabs}${dependency}"
    debug "find ${ROOT_LIB_DIRECTORY} -name ${dependency}"
    file=`find ${ROOT_LIB_DIRECTORY} -name ${dependency}|head -n 1`
    if [ -z "$file" ] ; then
        # Try lib.so*
        file=`find ${ROOT_LIB_DIRECTORY} -name ${dependency}*|head -n 1`
        if [ -z "$file" ] ; then
        [ ${QUIET_NOT_FOUND} -eq 0 ] && echo "ERROR : ${dependency} not found in ${ROOT_LIB_DIRECTORY}"
        [ ${EXIT_ON_ERROR} -eq 1 ] && exit 1
        continue
        else
        symlink_name=${dependency}
        fi
    fi
    # Already copied
    [ -e "${OUTPUT}/${dependency}" ] && continue
    copy $file ${symlink_name}
    find_lib $file
    done

    nb_tabs=$((${nb_tabs}-1))
}

function usage()
{
    echo "Usage : ./find_libs [-O OBJDUMP] [-v] [-e] [-q] [-c] [-C] -t TARGET -o OUTPUT_DIR -l ROOT_LIBDIR"
    echo -e "\t-O OBJDUMP      objdump command"
    echo -e "\t-v              verbose"
    echo -e "\t-e              exit on error"
    echo -e "\t-q              quiet when dependency not found"
    echo -e "\t-c              clean target before start"
    echo -e "\t-C              Copy target in output directory"
    echo -e "\t-t TARGET       first executable or library to analyze"
    echo -e "\t-o OUTPUT_DIR   output directory where to place find libs"
    echo -e "\t-l ROOT_LIBDIR  root directory where to search dependancy libs"
}

while getopts "ht:o:l:O:veqcC" arg; do
    case $arg in
    t)
        TARGET=$OPTARG
        ;;
    o)
        OUTPUT=$OPTARG
        ;;
    l)
        ROOT_LIB_DIRECTORY=$OPTARG
        ;;
    O)
        OBJDUMP=$OPTARG
        ;;
    v)
        VERBOSE=1
        ;;
    e)
        EXIT_ON_ERROR=1
        ;;
    q)
        QUIET_NOT_FOUND=1
        ;;
    c)
        CLEAN_BEFORE_START=1
        ;;
    C)
        COPY_TARGET=1
        ;;
    h)
        usage
        ;;
    *)
        usage
        ;;
  esac
done

if [ -z "${TARGET}" -o -z "${OUTPUT}" -o -z "${ROOT_LIB_DIRECTORY}" ] ; then
    usage
    exit 0
fi

[ ${CLEAN_BEFORE_START} -eq 1 ] && rm -rf ${OUTPUT}

mkdir -p ${OUTPUT} || exit 1

echo ${TARGET}
[ ${COPY_TARGET} -eq 1 ] && copy ${TARGET}

find_lib ${TARGET}

A file version is available here

Sunday, 04 July 2021
|
Écrit par
Grégory Soutadé

Two months ago I released a software that can use librmsdk.so from Adobe in order to retrieve ePub files (with Adobe DRM) from ACSM request files. It was the result of a long work of reverse engineering. The main problem with it is that it requires to run on an ARMv7 platform.

When I published it, I felt I can go further, but I was afraid of counter measures or cryptic algorithms that can be used by Adobe. Nevertheless, thanks to all knowledge acquired by my first reverse attempt I decided to try. In the end, Adobe choose to use standard algorithms with no obfuscation (maybe because it's delivered with a full SDK for clients). Plus, the target library wasn't compiled with code optimization \o/.

So I'm pleased to announce the first release of libgourou. It's a Free and Open Source implementation of ADEPT protocol. It supports :

  • Account signIn
  • Device activation
  • ePub download from ACSM request file

In addition to libgourou, two utils acsmdownloader and activate are provided in order to create a new device and download ePub from your favorite UNIX platform (like Linux x86/amd64 !) without any call to Adobe's code (no ADE, no WINE !).

Like RMSDK, it's based on a client/server model were the client has to implement some system specific functions (network, crypto...). It allows the library to be very portable (it's written in C++ 11).

The library by itself is licensed under LGPLv3 and the client (reference implementation) is under BSD license.

I can now tell it : we have a real alternative to ADE for Linux platforms !

Source are available on my forge

Sunday, 27 June 2021
|
Écrit par
Grégory Soutadé

Champs de lavandes

Quand on commence à évoquer une destination pour les vacances, la Drôme n'est pas le premier lieu auquel l'on pense. Pourtant c'est un département qui offre de multiples facettes.

Plaine Drômoise

L'aspect le moins intéressant est peut-être la vaste plaine entre Montélimar et Romans Sur Isère. Fréquemment balayée par les vents, elle bénéficie d'un ensoleillement exceptionnel tout au long de l'année, c'est pour cela que la culture des fruits et légumes y est importante. Il peut y faire assez chaud, l'air sec rend cependant le climat un peu plus supportable.

Le fait qu'il y ait peu de dénivelé encourage à la pratique du vélo (surtout dans les villes). L'inconvénient est que les agglomérations n'hésitent pas à construire de vastes zones commerciales et industrielles qui s'étalent parfois à perte de vue (notamment du côté de Montélimar).

Campagne Drômoise

Mais la Drôme possède de nombreuses richesses : au Nord Est, le massif du Royan, à l'Est, le massif du Vercors (bien que tous deux souffrent de la popularité des Alpes). Au Sud, la partie Provençale. À l'Ouest, le Rhône qui la sépare de l'Ardèche, au Nord, les coteaux.

Coquelicots dans un champs de blés

La proximité du Rhône est un atout fort de la région qui a permit son développement depuis l'époque Gallo Romaine jusqu'au milieu du XXe siècle. Il y a ensuite eu des disparités importantes avec un exode rural, notamment vers l'aire Valentinoise ainsi que Montélimar. Le coût de la vie étant inférieur dans une grande partie du département, permet aux familles plus modestes d'y vivre convenablement, même si les emplois restent concentrés dans les "grandes" villes. On y trouve d'ailleurs quasi systématiquement un établissement proposant le trio magique : tacos/kebab/burger. À l'opposé et à des prix complètement inaccessibles, les établissements Pic (hôtel et restaurant (3 étoiles au guide Michelin)) font la réputation de la région. Entre les deux, il y a bien entendu une offre assez complète avec deux restaurants 1 étoile dans la seule ville de Valence. Ce genre d'opposition est plutôt fréquente dans la région. C'est un territoire très agricole avec un fort savoir faire artisanal, donc plutôt traditionnel, mais où émerge un peu partout une certaine dynamique portée par la jeunesse et l'innovation.

La meilleure saison pour visiter la Drôme étant sûrement juin : les lavandes sont en fleurs (et pas encore récoltées), les fruits et légumes commencent à arriver sur les étals, il ne fait pas encore trop chaud et l'affluence touristique est naissante. Le mieux étant de loger dans un chambre d'hôte (à la campagne pour être un peu au vert) afin de profiter de l'expérience des propriétaires.

Quelques points intéressants à visiter (liste non exhaustive) :

Orange

Arc de triomphe d'Orange Petite place d'Orange

Sans trop s'y attarder, le centre ancien offre des vestiges gallo-romain très intéressants comme l'arc de triomphe ou encore un théâtre antique encore complet (en restauration pour le moment).

Montélimar

Il faut aller dans une des fabriques (ou (mini) musée) de nougat, mais il y a également le musée de l'aviation de chasse.

Grignan

Grignan

Ses champs de lavandes et son célèbre château cher à madame de Sévigné.

Crest

Tour de Crest

Son village ancien et surtout sa tour, ancienne prison d'état.

Crest

Rue de Crest

Les gorges d'Omblèze

Gorges d'Omblèze

Pour se mettre un peu au frais. Au centre coule la Gervanne qui est ... très froide !

Lama à Léoncel

Le Vercors

Plaine au creux du Vercors

Pour se mettre encore plus au frais. Entre Crest et le point le plus froid du Vercors, il peut y avoir une différence de température de 10°C ! C'est un lieu idéal pour y faire du vélo pour ceux qui aiment le dénivelé ou de la moto pour les amateurs. En général on fait une halte pour visiter l'abbaye de Léoncel.

Une partie du plateau d'Ambel

Le plateau d'Ambel pour des balades en famille. Sans oublier les multiples randonnées que l'on peut faire dans le Vercors.

Route de la combe Laval

La route qui longe la combe de Laval, creusée à flanc de falaise ! Un conseil : faire le trajet en deux roues.

Le Royans

La Bourne

Et ses fameuses ravioles.

Saint Nazaire En Royans et son Aqueduc qui surplombe la Bourne.

Saint Jean En Royans où l'on pourra visiter la distillerie du Vercors.

Romans-sur-Isère

Romans sur Isère

Ancien haut lieu de la chaussure Française. Il ne faut pas hésiter à aller au musée de la chaussure qui occupe actuellement un ancien couvent. Ce dernier propose une exposition qui retrace l'histoire de la chaussure à Romans, en Europe et dans le monde, d'hier à aujourd'hui. Non loin de là, la cité de la chaussure réunit une partie de la production d'entreprises locales qui ont choisi de redonner vie à ce savoir faire (de surcroît avec des prix abordables).

Tain-l'Hermitage

Le Rhône à Tain-l'Hermitage

Pour la cité du chocolat de Valrhona ! On y verra également les coteaux de l'AOP Hermitage.

Le Rhône

Avec la piste cyclable ViaRhôna qui part de Genève jusqu'à Sète.

Cliousclat

Rue de Cliousclat

Cité de la poterie. Ce petit village possède une architecture typique de la région avec les bâti en pierres rondes du Rhône.

Rue de Cliousclat

Mirmande

Figuier à Mirmande

Un des plus beaux villages de la Drôme. La cité regroupe nombre d'artisants locaux. Il faudra cependant avoir des cuisses musclées pour grimper tout en haut !

L'Ardèche toute proche

Château de la Voulte-sur-Rhône

Juste de l'autre côté du Rhône, la Voulte-sur-Rhône et son château incendié par les nazis.

Passage de la Voulte-sur-Rhône

Valence

Logo Valence

L'incontournable chef lieu de la région. C'est une ville jeune et dynamique avec un (petit) centre charmant.

Bylo design

Pour la petite anecdote, il était environ 21h, la petite porte de l'art shop "Bylo Design" était ouverte. Petit passage de tête à l'intérieur "Est-ce que la boutique est ouverte ?". "Bien sûr !". Et c'était parti pour la découverte de la sérigraphie sur textile, métier et passion de Laurent depuis presque deux décennies avant qu'il n'ouvre en début d'année sa boutique dans le centre. Contrairement au flocage, ce n'est pas l'application d'un calque texturé sur du textile, mais plutôt d'une peinture thermofixée qui fera corps avec le textile (donc d'une qualité professionnelle qui dure dans le temps). L'objectif de Laurent n'est pas de créer une gamme, mais de réaliser les projets de ses clients (qu'ils soient plus ou moins aboutis). Il y a quand même quelques exemplaires en boutique de son cru ainsi que d'autres artistes. Un de ces exemplaires n'était pas disponible pour homme. Qu'importe qu'il soit déjà 22h, Laurent a eu la gentillesse de le réaliser en direct !

Champs de Mars - Valence Place à Valence

Monday, 24 May 2021
|
Écrit par
Grégory Soutadé

Affiche Adieu les cons

J'étais assez dubitatif lorsqu'Albert Dupontel (ici scénariste, acteur et réalisateur) a sorti Adieu les cons l'année dernière. À priori, un film dans lequel Virginie Effira (alias Suze), atteint d'une maladie auto immune à l'âge de 43 ans décide d'utiliser le peu de temps qui lui reste à vivre pour rechercher l'enfant qu'elle a accouché sous X 15 ans plus tôt, n'est pas forcément ma tasse de thé. D'autant plus que la bande annonce montre des passages assez simplistes.

Pourtant ce film est un véritable petit bijou, tant sur le fond que sur la forme. Les mauvaises langues diront qu'il n'y a pas eu de concurrence réelle, mais les 7 Césars reçus (sur 13 nominations) sont largement mérités ! Albert Dupontel déclarait dans Passage des arts qu'il ne "faisait qu'enfoncer des portes ouvertes". C'est exact si on s'en tient au squelette de l'action. Néanmoins, le développement qui est fait autour de ce squelette est tout simplement extraordinaire avec énormément de poésie, de justesse et d'harmonie dans le jeu des acteurs principaux comme secondaires, avec un déroulement authentique, qui ne tente pas de prendre de raccourcis, qui laisse l'histoire se décanter, se construire pour amener à une charge émotionnelle forte sans jamais tomber dans la niaiserie. Pour supporter son propos, l'auteur ajoute régulièrement des éléments comiques qui viennent sublimer l'action sans prendre le pas sur celle-ci (contrairement à ce que suggère la bande annonce). Tous ces éléments permettent de faire oublier les quelques parties extraordinaires du personnage principal incarné par Dupontel, qui relèvent plus du conte moderne. Et que dire de la réalisation ? Sublime. Que ce soit dans le cadrage, toujours juste, l'utilisation judicieuse des effets spéciaux, l'esthétique qui est juste extraordinaire, avec un immense travail sur la photo (Surtout que beaucoup de plans se déroulent de nuit où on retrouve tout un panel de couleurs chaudes).

Mon dernier coup de cœur cinéma date de 2009 avec Parasite. Dans un autre registre Adieu les cons est à sa hauteur et j'encourage fortement les spectateurs à profiter de la réouverture des salles pour foncer voir ce (pas si) long métrage (1h27) pendant qu'il est encore à l'affiche !

Thursday, 13 May 2021
|
Écrit par
Grégory Soutadé

WARNING : You can also use libgourou and its utils to do the same thing from your platform (standard Linux PC), see this article

I finally did it ! After a long time looking for software that can download EPUB from ACSM file on Linux without need to install WINE software (and an old ADE version), I found the right breach to exploit.

As every Linux user knows, Adobe doesn't provide any support for ADE software on Linux, so we can't download EPUB files protected with Adobe ADEPT DRM because when you buy an ebook you get some ACSM file which is a request file for an ACS server (Adobe Content Server) that encrypts your ebook before returning it. My goal is not to have them decrypted, but just get the EPUB and put it on my eReader (an old Cybook Odyssey) to read it without rebooting on Windows. I can do it easily if I use the integrated bookshop, but :

  • I got a notification it will not work anymore (no support from Bookeen) even if it's still works...
  • I can't easily buy books from other shops

Time to time I look for resources on ADEPT DRM, Linux support, try to reverse protocol, exploit some binaries... I found my way thanks to Kobo firmware updates which include a precompiled version of librmsdk.so (Adobe Reader Mobile SDK) for Linux/ARMv7. I worked a lot with ARMv7 platforms, so it's not a problem for me to reverse it, plus my own server is ARMv7 compatible (iMX6) !

The shared library doesn't contains debug symbols (it's stripped). But it's a shared library, so it needs to expose all entry points in clear. Using readelf util we can find all of them and start to call it without Adobe headers. I first tried to exploit libnickel.so which is implemented by Kobo. It's an upper layer and I hoped it'll be easier to access high level functions. It was not and I decided to directly call librmsdk.so (which is lighter and has few dependencies).

RMSDK is written in C++ which is nice for application developers but a bit more tricky for reverse engineers, especially with virtual functions. Thanks for me the library is compiled without optimization options which make it more human readable.

It was a nice start but I lost a lot of time trying to find API by hand using readelf. So I developed SOAD (SO Advanced Dissector) a Python script which helps me to find automatically the full SO exported C++ API and generate (almost) ready to build C++ headers. It took me some time, but in the end helps me a lot. I was first doubtful this script can produce something interesting and I shouldn't ! I was impressed with the first simple version that produced very nice results ! So I decided to continue to work on it to handle more and more complex cases. One interesting thing was vtable discovery. The script statically parses vtables entries, but code compiled with fPIC option (which is the case here) has these entries filled with 0 which doesn't helps us. Fortunately, Andrey Ponomarenko created vtable-dumper which is a runtime vtable dumper (need to be executed on target platform). I used its output to find all zeroed vtable entries, but I also improved it to display class hierarchy !

I had to go in depth with C++ ABI and some C++ mechanism that are most of the time transparent for user (copy constructor, = operator, implicit cast, virtual tables and so on). Now the hard (and interesting) part is done, I'll make a little web app that will manage ACSM download and EPUB storage for an easy access from my eReader (avoid SSH, command line call and USB copy).

Sources are available in my forge here. I cannot embbed librmsdk.so as I don't have any Adobe license, but there is a script to retrieve it. The only license I got is GPLv3 !

Dernier gif les joies du code Quand les experts sécurité s’avèrent être moins compétents que prévu