histoire
Leur ambition, remettre le cerveau au cœur du consulting.
Pour y parvenir, ils décident de créer une société où les curieux pourront satisfaire leur soif de connaissances et développer leurs savoirs. Parce que le savoir va au delà des mots, ils décident que tout élément de leur discours doit être prouvable.
"Pas de baratin, les cerveaux ne sont pas dupes."
—
Diplômé d'une école d'ingénieur, génie de la programmation; seul informaticien capable de programmer un hydravion traversant littéralement des montagnes, Laurent débute sa carrière en tant qu'ingénieur informatique.
Frappé de plein fouet par le bug de l'an 2000, il disjoncte et change de métier. Véritable Alice aux pays des merveilles 2.0, il traverse le miroir et se rend compte qu'en réalité, sa vraie valeur ajoutée, réside dans la découverte et l'accompagnement de talents.
À 45 ans à l'âge ou certains se mettent à la tisane, au macramé et aux charentaises il rejoint Franck pour structurer et développer Cerebris.
—
Franck aime la nature, les grands espaces et l'aventure. Il a d'autres passe-temps moins avouables, mais pour en savoir plus, il faudra le questionner (lors d'un apéro par exemple).
Manager de formation (si si ça existe), Franck a choisi le C++ en LV2 et le Java en LV3. Cela explique sans doute son niveau d'anglais.
Une légende raconte qu'il est resté prisonnier durant 7 ans d'une grosse société de service. Il parait même que pour ne pas oublier ce qu'il a fuit, il s'est fait tatouer le business model de la dite entreprise dans le dos.
preuves
Références
Réalisations
Nos référents techniques s’investissent pour faire vivre les technos et accompagner les autres cerebristes.
Vous voulez en faire partie ? Dites-le nous !
Découvrez ci-dessous ce qu'ils savent faire
include <pthread.h>
include <event2/event.h>
define TIMEOUT_IN_SECONDS 50
void timer_loop_thread(void arg)
{
struct context p_context = (struct context )arg;
struct timeval tv;
int fd[2];
memset(&tv, 0, sizeof(struct timeval));
tv.tv_sec = TIMEOUT_IN_SECONDS;
// pipe creation for read and write file descriptor
pipe2(fd,O_NONBLOCK);
p_context->fd_read = fd[0];
p_context->fd_write = fd[1];
p_context->p_evbase = event_base_new();
// read_msg is the callback triggered on new event income
p_context->p_event = event_new(p_context->p_evbase, p_context->fd_read,
EV_READ|EV_PERSIST,read_msg,p_context);
event_add(p_context->p_event, 0);
// timer_callback is called when the timer is triggered
p_context->p_evtimer = evtimer_new(p_context->p_evbase, timer_callback, p_context);
evtimer_add(p_context->p_evtimer, &tv);
// event loop
event_base_dispatch(p_context->p_evbase);
pthread_exit(NULL);
}
Dans le cas présent, un timer est mis à jour. Il peut être remis à jour depuis un autre thread en utilisant le file descriptor write.
C'est l'utilisation du pipe qui permet de rester thread-safe.
struct FileDateComparator
{
bool operator() (const std::string &left, const std::string &right)
{
struct stat leftStats;
struct stat rightStats;
stat(left.c_str(), &leftStats);
stat(right.c_str(), &rightStats);
return leftStats.st_mtime > rightStats.st_mtime;
}
};
// Real sort on chunks files
FileDateComparator dateComparator;
std::sort(chunkFilesList.begin(), chunkFilesList.end(), dateComparator);
L'utilisation de la méthode sort de la bibliothèque standard algorithm et d'un comparateur personnalisé nous a permis d'optimiser les performances de la solution.
List<User> musicians = new ArrayList<>();
// Get the users list from each registration item
this.registrations.forEach((registration -> musicians.add(registration.getUser())));
return musicians;
}
Varb=array("WebButton","Click Here")
Set obj=testObj.Find(VarA,VarB,10)
If obj.Exists then
obj.click
else
msgbox "No object found"
End if
L'automatisation a permis ainsi un gain de temps de 40% sur certaines phases et de pouvoir lancer des tests nocturnes.
struct timeval now;
int i;
int j;
char str[64];
long long number;
pthread_mutex_lock(&struct->arguments->lock_status);
gettimeofday(&now, NULL);
number = ((now.tv_sec - struct->arguments->start_struct.tv_sec) * 1000
+ (now.tv_usec - struct->arguments->start_struct.tv_usec) * 0.001);
i = print_nbr(number, str);
j = 0;
str[i++] = '\t';
while (struct->num_struct[j])
str[i++] = struct->num_struct[j++];
str[i++] = '\t';
while (*msg)
str[i++] = *(msg++);
if (check_end(struct) == 0)
write(1, str, i);
pthread_mutex_unlock(&struct->arguments->lock_status);
# export K8SCLUSTER_IMAGE="centos/8" # KO on k8s-master need review
# export K8SCLUSTER_IMAGE="debian/stretch64" # Debian 9.12.0
# export K8SCLUSTER_IMAGE="debian/buster64" # Debian 10.4.0 (VirtualBox 6.1 Only)
# export K8SCLUSTER_IMAGE="bento/ubuntu-16.04" # Ubuntu 16.04
# export K8SCLUSTER_IMAGE="ubuntu/xenial64" # Ubuntu 16.04 (VirtualBox 5.2 Only)
# export K8SCLUSTER_IMAGE="ubuntu/bionic64" # Ubuntu 18.04
# export K8SCLUSTER_IMAGE="ubuntu/focal64" # Ubuntu 20.04
# Use K8SCLUSTER_IMAGE environment variable to override default image name.
K8SCLUSTER_IMAGE = "#{ENV['K8SCLUSTER_IMAGE']}"
K8SCLUSTER_IMAGE = "centos/7" if K8SCLUSTER_IMAGE.empty?
N = 2
# Link content of ./inventory into .vagrant/provisioners/ansible/inventory to
# reuse group definitions and group_vars.
vagrant_inventory = File.join(File.dirname(__FILE__),
".vagrant", "provisioners", "ansible", "inventory")
FileUtils.mkdir_p(vagrant_inventory) if ! File.exist?(vagrant_inventory)
Dir.foreach("inventory") do |item|
ln_lnk = File.join(vagrant_inventory, item)
ln_trg = File.join("..", "..", "..", "..", "inventory", item)
FileUtils.ln_s(ln_trg, ln_lnk) if ! File.exist?(ln_lnk)
end
# Define box default interface
k8scluster_default_ifname = {
"ubuntu/bionic64" => "enp0s8",
"ubuntu/focal64" => "enp0s8",
}
k8scluster_default_ifname.default = "eth1"
# Define machine variables
k8scluster_hosts = Array.new
k8scluster_hosts_vars = {}
(0..N).each do |i|
host_ip = "172.16.50.#{10 + i}"
k8scluster_hosts[i] = {
"host_ip" => host_ip,
"host_name" => "k8s-node-%02d" % i
}
end
# Apply master specifics k8scluster_hosts[0]["host_name"] = "k8s-master"
Vagrant.configure("2") do |config|
config.ssh.insert_key = false
config.vm.provider "virtualbox" do |v|
v.memory = 3072
v.cpus = 2
end
Il est exécuté à chaque merge-reqest afin de valider les modifications des scripts Ansible poussées sur GitLab et éviter ainsi tous les risques de régression.
# SPDX-License-Identifier: GPL-3.0-or-later
# Installation steps : (install)
# -> 1. prepare
# 2. download
# 3. configure
# 4. activate
- name: Prepare - Install required dependencies
ansible.builtin.package:
state: present
name: "{{ item }}"
loop: >-
{%- if ansible_os_family == "RedHat" %}
{%- set package_list = ["epel-release", "python-virtualenv"] %}
{%- else %}
{%- set package_list = ["virtualenv"] %}
{%- endif %}
{{- package_list | union(["python3-pip"
if (ansible_python.version.major == 3) else "python-pip"]) }}
- name: Prepare - Create project directory
ansible.builtin.file:
path: "{{ stack_project.path }}"
state: directory
- name: Prepare - Create virtualenv and Update pip
ansible.builtin.pip:
state: present
# pip 21.0 dropped support for Python 2.7 and Python 3.5 in January 2021
name: "{{ 'pip' if (ansible_python.version.major == 3 and
ansible_python.version.minor >= 6) else 'pip==20.2.*' }}"
extra_args: -U
virtualenv: "{{ stack_project.path }}venv/"
virtualenv_site_packages: yes
- name: Prepare - Install python dependencies
ansible.builtin.pip:
state: present
# pyrsistent is required by docker-compose, the version 0.17.2 does not
# support python 2.7 and pip does not always choose the right one.
name:
- cryptography
- "{{ 'pyrsistent' if ansible_python.version.major == 3 else
'pyrsistent==0.16.1' }}"
- docker
- docker-compose
virtualenv: "{{ stack_project.path }}venv/"
- name: Prepare - Create docker-compose.yml
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ stack_project.path }}docker-compose.yml"
notify: Restart systemd
- name: Prepare - Create systemd service configuration
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
loop:
- src: docker-compose.service.j2
dest: "/etc/systemd/system/{{ stack_project.name }}.service"
notify: Reload systemd
1. Vérification de la connexion entre la flash SPI et la raspberry pi et identification de la flash
$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=128k
Found Macronix flash chip "XXXXXXXXXX" (YYYYkB, SPI) on linux_spi.
Found Macronix flash chip "XXXXXXXXXXX/XXXXXXXXX" (YYYYkB, SPI) on linux_spi.
Found Macronix flash chip "XXXXXXXXXXX/XXXXXXXXXXXXX/XXXXXXXXXXXXXX" (XXXX kB, SPI) on linux_spi.
Multiple flash chip definitions match the detected chip(s): "XXXXXXXXXX", "XXXXXXXXXXX/XXXXXXXXX", "XXXXXXXXXXX/XXXXXXXXXXXXX/XXXXXXXXXXXXXX"
Please specify which chip definition to use with the -c
2. Extraction de la flash, en précisant la "chip definition" correspondant à notre modèle
$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=128k -c "XXXXXXXXXX" -r extracted_flash.raw
$ ls -l extracted_flash.raw
-rw------- 1 xxxx XXXX 4.0M Jun 01 01:01 extracted_flash.raw
3. Extraction de l'image
$ binwalk -e extracted_flash.raw
$ ls _extracted_flash.raw.extracted
0.squashfs squashfs-root
$ ls _extracted_flash.raw.extracted/squashfs-root
bin data dev etc extracted hook.so launch lib media mnt opt proc sbin share sys tmp usr var var.old www
4. Enjoy, on peut maintenant émuler, reverser ou bien fuzzer.
Afin d'émuler, fuzzer il sera nécessaire d'installer un émulateur et de patcher si nécessaire le binaire, certaines fonctionnalités peuvent être propre au SOC.
Cela pourra se faire en utilisant des fonctionnalités tel que LD_PRELOAD et en créant une librairie patcher, ou bien en patchant directement le binaire par exemple.
image:spi_simle.svg
Schémas de branchement d'une flash SPI pour une extraction via raspberry pi, avec reset du SOC.
La mise en état de reset du SOC est nécessaire pour prendre le contrôle de la flash (dans le cas où le SOC est alimenté avec la flash).
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Mon application Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Exemple Flutter'),
),
body: Center(
child: Text(
'Bonjour, monde !',
style: TextStyle(fontSize: 24),
),
),
),
);
}
}
L'utilisation de Flutter permet de développer des applications multiplateformes avec une seule base de code. Flutter utilise le langage Dart et fournit des widgets réactifs qui facilitent la création d'interfaces utilisateur fluides et attrayantes. Dans cet exemple, nous avons utilisé des widgets de base tels que MaterialApp, AppBar, Text, etc.
En conclusion, nous avons utilisé cette fonction Flutter pour présenter une structure de base d'une application Flutter, en utilisant des widgets et en démontrant comment démarrer une application Flutter. Cela nous permet de créer rapidement des interfaces utilisateur attrayantes et réactives pour les applications mobiles et web.
{
if(!dlCompute.predict(inputImage_in, outputImage_out)) // Compute heat map from model
return false;
outputImage.convertTo(outputImage_out, CV_8U); // Convert heat map to 8 bits image (0 to 255)
cv::threshold(outputImage_out, outputImage_out, 50, 255, cv::THRESH_BINARY); // Threshold heat map to create an image mask
// Post process of segmentation with mathematical morphology
cv::morphologyEx(outputImage_out, outputImage, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3.0, 3.0))); // Opening -> Remove noise
cv::morphologyEx(outputImage_out, outputImage, cv::MORPH_CLOSE, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3.0, 3.0))); // Closing -> close structures
return true;
}
from art.attacks.evasion import FastGradientMethod
from art.estimators.classification import SklearnClassifier
classifier = SklearnClassifier(model=model)
classifier.fit(x_train, y_train)
# Evaluate the classifier on benign test examples
predictions = classifier.predict(x_test)
accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_test, axis=1)) / len(y_test)
print("Accuracy on benign test examples: {}%".format(accuracy * 100))
# Generate adversarial test examples
attack = FastGradientMethod(estimator=classifier, eps=0.2)
x_test_adv = attack.generate(x=x_test)
# Evaluate the classifier on adversarial test examples
predictions = classifier.predict(x_test_adv)
accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_test, axis=1)) / len(y_test)
print("Accuracy on adversarial test examples: {}%".format(accuracy * 100))
Ici nous utilisons la méthode FastGradientMethod pour générer des attaques.
FastGradientMethod est une méthode d'attaque permettant de générer des exemples adversaires en calculant les gradients de la fonction de coût par rapport aux données d'entrée et en ajustant les valeurs des données pour induire des erreurs dans les modèles de machine learning.
Nous allons ainsi comparer l'accuracy, qui est une métrique pour évaluer la performance des modèles de classification, du modèle ayant subi des attaques avec celui qui n'en a pas subi et vérifier la robustesse du modèle d'intelligence artificielle.
Savoir-faire
Aéro défense
Healthcare
Transportation
Energies renouvelables
Tertiaire
Telecom
Nos locaux
Miscellanews Letter
actu
en (cer)veau deux
Contact
téléphone — 01 42 84 34 08
email — hello@cerebris.fr
Nous rencontrer :
6 rue Maurice Loewy
75014 Paris