Defusing CMU's Bomb Lab using GDB (8/28/20)
This post walks through CMU’s ‘bomb’ lab, which involves defusing a ‘bomb’ by finding the correct inputs to successive phases in a binary executable using GDB.
Post Outline
Intro
This post walks through the first 3 phases of the lab. I used a linux machine running x86_64. Also note that the binary follow the AT&T standard so instruction operations are reversed (e.g. mov a b moves data from a to b as opposed to b to a).
GDB
Here are a few useful commands that are worth highlighting:
layout asm
This command divides the screen into two parts: the command console and a graphical view of the assembly code as you step through it. Control-l can be used to refresh the UI whenever it inevitably becomes distorted. While layout asm is helpful, also helpful for full object dump objdump -d path/to/binary Can easily search through the entire assembly file!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
i r
This command lists out all the values that each of the registers hold.
i b
This command lists all the current breakpoints as well as how many times each breakpoint has been hit on the current run.
b *memory address, function name
This command sets breakpoints throughout the code. Breakpoints can be set at specific memory addresses, the start of functions, and line numbers.
x memory address, register
This command prints data stored at a register or memory address. It is useful to check the values of these registers before/after entering a function. For example, after a function has finished executing, this command can be used to check the value of $rax to see the function output.
Phase 1
We can then set up a breakpoint upon entering phase_1
using b phase_1
and for the function explode_bomb
to avoid losing points.
Using layout asm
, we can see the assembly code as we step through the program.
Let’s enter the string blah
as our input to phase_1
.
When we hit phase_1
, we can see the following code:
0000000000400ee0 <phase_1>:
400ee0: 48 83 ec 08 sub $0x8,%rsp // allocate space on the stack
400ee4: be 00 24 40 00 mov $0x402400,%esi // move data from some memory to esi register
400ee9: e8 4a 04 00 00 callq 401338 <strings_not_equal> // call a function
400eee: 85 c0 test %eax,%eax
400ef0: 74 05 je 400ef7 <phase_1+0x17> // if eax is equal, avoided the bomb
400ef2: e8 43 05 00 00 callq 40143a <explode_bomb>
400ef7: 48 83 c4 08 add $0x8,%rsp
400efb: c3 retq
The code is annotated with comments describing each line.
We see that a strings_not_equal
function is being called.
From this, we can guess that to pass phase_1
, we need to enter the correct string.
Let’s set a breakpoint at strings_not_equal
.
Once we enter the function, we can check the registers that store the first two inputs: $rdi and $rsi.
We can see that our string input blah
is being compared with the string Border relations with Canada have never been better.
.
Entering this string defuses phase_1.
Phase 2
Let’s clear all our previous breakpoints and set a new one at phase_2
.
Let’s use blah
again as out input for phase_2
.
We can now see the assembly code. Each line is annotated.
0000000000400efc <phase_2>:
400efc: 55 push %rbp
400efd: 53 push %rbx
400efe: 48 83 ec 28 sub $0x28,%rsp
400f02: 48 89 e6 mov %rsp,%rsi
400f05: e8 52 05 00 00 callq 40145c <read_six_numbers> // read 6 numbers
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp) // check to see that first # is 1
400f0e: 74 20 je 400f30 <phase_2+0x34>
400f10: e8 25 05 00 00 callq 40143a <explode_bomb>
400f15: eb 19 jmp 400f30 <phase_2+0x34>
400f17: 8b 43 fc mov -0x4(%rbx),%eax // move the previous number into %eax
400f1a: 01 c0 add %eax,%eax // double %eax
400f1c: 39 03 cmp %eax,(%rbx) // compare %eax and the current number
400f1e: 74 05 je 400f25 <phase_2+0x29> // if equal, avoid bomb
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
400f25: 48 83 c3 04 add $0x4,%rbx
400f29: 48 39 eb cmp %rbp,%rbx
400f2c: 75 e9 jne 400f17 <phase_2+0x1b> // jump back to 400f17
400f2e: eb 0c jmp 400f3c <phase_2+0x40> // otherwise end of loop, exit
400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx
400f35: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp
400f3a: eb db jmp 400f17 <phase_2+0x1b>
400f3c: 48 83 c4 28 add $0x28,%rsp
400f40: 5b pop %rbx
400f41: 5d pop %rbp
400f42: c3 retq
From the code, we can see that we first read in 6 numbers.
To see the format of how we enter the six numbers, let’s set a breakpoint at read_six_numbers
.
000000000040145c <read_six_numbers>:
40145c: 48 83 ec 18 sub $0x18,%rsp
401460: 48 89 f2 mov %rsi,%rdx
401463: 48 8d 4e 04 lea 0x4(%rsi),%rcx
401467: 48 8d 46 14 lea 0x14(%rsi),%rax
40146b: 48 89 44 24 08 mov %rax,0x8(%rsp)
401470: 48 8d 46 10 lea 0x10(%rsi),%rax
401474: 48 89 04 24 mov %rax,(%rsp)
401478: 4c 8d 4e 0c lea 0xc(%rsi),%r9
40147c: 4c 8d 46 08 lea 0x8(%rsi),%r8
401480: be c3 25 40 00 mov $0x4025c3,%esi // Move some value into a register
401485: b8 00 00 00 00 mov $0x0,%eax
40148a: e8 61 f7 ff ff callq 400bf0 <__isoc99_sscanf@plt> // scanf() is called
40148f: 83 f8 05 cmp $0x5,%eax
401492: 7f 05 jg 401499 <read_six_numbers+0x3d>
401494: e8 a1 ff ff ff callq 40143a <explode_bomb>
401499: 48 83 c4 18 add $0x18,%rsp
40149d: c3 retq
From the above, we see that we are passing some value into a register before calling scanf()
.
Knowing that scanf()
takes in a string format as its input, let’s break right before scanf()
is called and check the value of $esi.
(gdb) x /s $esi
0x4025c3: "%d %d %d %d %d %d"
From this, we can see that the input format of read_six_numbers
should be 6 space-separated integers.
Going back to the code for phase_2
, we see that the first number has to be 1
.
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp) // check to see that first # is 1
400f0e: 74 20 je 400f30 <phase_2+0x34>
400f10: e8 25 05 00 00 callq 40143a <explode_bomb>
400f15: eb 19 jmp 400f30 <phase_2+0x34>
We then move onto the next few lines.
400f17: 8b 43 fc mov -0x4(%rbx),%eax // move the previous number into %eax
400f1a: 01 c0 add %eax,%eax // double %eax
400f1c: 39 03 cmp %eax,(%rbx) // compare %eax and the current number
400f1e: 74 05 je 400f25 <phase_2+0x29> // if equal, avoid bomb
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
400f25: 48 83 c3 04 add $0x4,%rbx
400f29: 48 39 eb cmp %rbp,%rbx
400f2c: 75 e9 jne 400f17 <phase_2+0x1b> // jump back to 400f17
400f2e: eb 0c jmp 400f3c <phase_2+0x40> // otherwise end of loop, exit
From the above annotations, we can see that there is a loop.
At each iteration, we check to see that the current value is double the previous value.
From this, we can deduce that the input for phase_2
should be 1 2 4 8 16 32
.
Phase 3
Let’s now set a breakpoint at phase_3
.
The following lines are annotated.
0000000000400f43 <phase_3>:
400f43: 48 83 ec 18 sub $0x18,%rsp
400f47: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
400f4c: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
400f51: be cf 25 40 00 mov $0x4025cf,%esi // reading $0x4025cf results in "%d %d"
400f56: b8 00 00 00 00 mov $0x0,%eax
400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt> // call scanf()
400f60: 83 f8 01 cmp $0x1,%eax
400f63: 7f 05 jg 400f6a <phase_3+0x27> // if output greater than 1 (read more than 1 number), avoid bomb
400f65: e8 d0 04 00 00 callq 40143a <explode_bomb>
400f6a: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp) // Compare out first number 0x8(%rsp) with 0x7
400f6f: 77 3c ja 400fad <phase_3+0x6a>
400f71: 8b 44 24 08 mov 0x8(%rsp),%eax
400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)
400f7c: b8 cf 00 00 00 mov $0xcf,%eax
400f81: eb 3b jmp 400fbe <phase_3+0x7b>
400f83: b8 c3 02 00 00 mov $0x2c3,%eax
400f88: eb 34 jmp 400fbe <phase_3+0x7b>
400f8a: b8 00 01 00 00 mov $0x100,%eax
400f8f: eb 2d jmp 400fbe <phase_3+0x7b>
400f91: b8 85 01 00 00 mov $0x185,%eax
400f96: eb 26 jmp 400fbe <phase_3+0x7b>
400f98: b8 ce 00 00 00 mov $0xce,%eax
400f9d: eb 1f jmp 400fbe <phase_3+0x7b>
400f9f: b8 aa 02 00 00 mov $0x2aa,%eax
400fa4: eb 18 jmp 400fbe <phase_3+0x7b>
400fa6: b8 47 01 00 00 mov $0x147,%eax
400fab: eb 11 jmp 400fbe <phase_3+0x7b>
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>
400fb2: b8 00 00 00 00 mov $0x0,%eax
400fb7: eb 05 jmp 400fbe <phase_3+0x7b>
400fb9: b8 37 01 00 00 mov $0x137,%eax
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax // compare our second input 0xc(%rsp) with value in %eax (682)
400fc2: 74 05 je 400fc9 <phase_3+0x86>
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9: 48 83 c4 18 add $0x18,%rsp
400fcd: c3 retq
From the above comments, we deduce that we want to input two space-separated integers.
The first number we can try to be 6 and the second must be 682.
Entering these numbers allows us to pass phase_3
.


Dundalk District Court
Dundalk man prosecuted for theft of Kanyé West runners
Court
by Court ReporterA 19-year-old man prosecuted for the theft of a pair of €460 trainers designed by rapper Kanyé West, has been placed under a bond at Dundalk district court to keep the peace and be of good behaviour for 12 months.
Omojolamiposi Bankole with an address at Point Road, Dundalk was also charged with possession of stolen property – a pair of Yeezy Beluga 2.0 runners, at his home on June 22nd last year.
The case had previously been adjourned for a Probation report after the Defence solicitor told the court the runners had been recovered and his client is a young man with no previous convictions who had never been in trouble before.


{% extends '_base.html' %} {% load static %} {% load core_tags %} {% block page_title %}Visualisations - {{ block.super }}{% endblock %} {% block head %} {{ block.super }} {% endblock %} {% block breadcrumbs %}
{% endblock %} {% block inner_content %}It looks like GitLab does not have a user record for you. Please visit GitLab, which will create one automatically. Then return to this page.
You do not have access to any visualisations in GitLab. If you think you should have access, please contact the Data Workspace Support Team.
{% endif %} {% for project in projects %}You have developer privileges on {{ project.name }}.
{% endif %}


Enter minimum number of genes/sites miRNA should regulate/pair to be shown in the results table
Example: You make request for 5 genes and put 3 into "Min genes" and 5 into "Min sites".
That means, that only miRNA, which regulate min 3 genes out of 5 and have 5 sites to pair
will be shown in the results.


|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
| Class Summary | |
|---|---|
| AbstractProjectDataAction | Abstract base class for a reversible operation on project data. |
| AddAudioDataAction | |
| ChangeAudioDataParameterAction | |
| ChangeEventParameterAction | |
| ChangeMixBusID | |
| ChangeNodeWithIDAndCommentsParameterAction | |
| ChangeSoundParameterAction | |
| CreateEventAction | |
| CreateGroupAction | |
| CreateMixBusAction | |
| CreateMixPresetAction | |
| CreateSoundAction | |
| CreateWaveBankAction | |
| MoveAudioDataAction | |
| MoveEventAction | Move an EventBase to an EventGroup |
| MoveGroupAction | |
| MoveMixBusAction | |
| MoveMixPresetAction | |
| MoveSoundAction | |
| MoveWaveBankAction | |
| RemoveAudioDataAction | |
| RemoveEventAction | |
| RemoveGroupAction | |
| RemoveMixBusAction | |
| RemoveMixPresetAction | |
| RemoveSoundAction | |
| RemoveWaveBankAction |
A package containing a number of classes representing actions that can be performed on project data. These classes are used in the undo/redo system of the Kowalski Editor.
|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


Rocky J. Reed
Gallery
Store
About & Contact
MENU
Gallery
Store
About & Contact
X
© Rocky J. Reed 2022


Normal
Quote
Text in bold, in italic, in underline, in red with yellow highlight
with
striked, with
superscript with
lowerscript and with a different
size
left centered
Middle centered
Right centered
spread
Indent1
Indent2
with a link to microsoft.com
table centered
| H1 | H2 | H3 |
|---|---|---|
| v1 | v2 | v3 |
| v12 | v22 | v32 |
| v13 | v23 | v33 |


- Second meeting, start to create Xibo VM and implemet
Week 3
- Another meeting, look into Xibo features for OP
Week 4
- Start Looking into the implementation of Codelingo-onprem solution
Week 5
- Discussion on open-source code
Week 6
- Struggling with Codelingo implementation
Week 7
- Created haphazardly functioning Codelingo-platform via splice of files
Week 8
- Start looking into GUI for .Lingo creation
Week 9
- Refine GUI for .Lingo creation
Week 10
- looking at BIT Platform problems / BIT DB
Week 11
- Start Work on CSV Reading
Week 12
- Give in CSV Readers
Week 13
- Automated lingo reviews from zombie server
Week 14
- Continue LingoBuilder development
- Create Poster
- Create technical documentation
Week 15
- Update OP-Codelingo platform
- Spin up CLWebServer
- Keep reworking LingoBuilder for showcase
- SHOWCASE
Professional Proficiency
Meeting Attendance
4/5
With the application of remote desktop to my personal machine and the majority of my subgroup assigned tasks relating only to myself, my presence within the project room was rather unnecessary. But I made sure that being present at the Monday and Thursday meetings was of paramount importance. Below can be found photos and recordings obtained from these congregations.
First meeting, assigned Xibo research
Second meeting, start to look into xibo
Another meeting, look into xibo features for OP
Discussion on open-source code
looking at BIT Platform problems / BIT DB
Given BIT Platform DB and CSV task
Communication With Peers
4/5
Although my group consisted of just me usually, there where several times when communication with peers was necessary, I believe in these instances I performed with an aura of professionalism. I must however admit that when I found myself in a tight predicament I would not continue to ask pertinent questions and would instead try to resolve the matter myself, such as the discussion of CodeLingo functionality to its respective staff. This would ultimately result in inefficient time management.
Asking Codelingo staff for assistance
Instructing Software-engineering team with prepared bundle
Exchanging updated SQL file and new CSV readers to team-member Lee
Project Documentation
3.5/5
My documentation throughout the project has unfortunately left much to be desired, as I struggled with CodeLingo software for many consecutive weeks I had failed to record what in particular was happening and in which week, leaving my timeline less robust than I would have hoped. I did however record all attended meeting information through the use of voice and note taking.
Most everything that I have worked upon this semester has been foreign to me, be it the implementation of virtual machines such as Xibo digital signage within vSphere to the strange complexities of CodeLingo. There have been tasks within this project that I have been able to achieve relatively fast and competently, although there have been many instances of problems where I cannot simply Google the question. It was a very frustrating experience and it mentally taxed me some days, but I felt that through it all I did well to find potential issues and solutions.
Trying to make heads or tails of how the Codelingo system functions
Technical Proficiency
Code Quality
3/5
Due to my projects nature, I haven’t particularly written much code, although I have produced several scripts for the lingo-builder server and the website itself. My strongest technical capabilities come from my Unix knowledge and OS understanding, which helped greatly in the BIT Platform group. Because of my chosen study path leaning more towards the world of systems administration my coding abilities have left my PHP/JavaScript pages suboptimal, but I believe I’m improving!
Code extract from lingo-builder / calling server-side scripts
Following Development Best Practices
3/5
I feel that when it comes to best practices, I try my best to make things I develop simple and user friendly whilst also testing in a few various environments. A good example may be me always implementing new updates for CodeLingo software such as the platform or lingo binaries on my own home machine by just utilizing VMWare Workstation. I can then diagnose any potential problems in a well understood environment before pushing to the servers located at OP. However, I understand that one of my largest downfalls is not regularly using industry recognized version controls such as git.
Trying to create a GUI that is simple and understandable
Also in the Pursuit of minimalism
VMs running test on personal environment
Version Control
3/5
Not the best. I recognize that I implemented proper version control a bit late. As when I was developing my projects it was only me utilizing the code or software, so I only employed the 2 separate backups in 2 different locations approach. Usually I would have my software stored on my personal machine, external hard drive and project machine but as the end drew near I started to employ the use of git.
To little to late
On-site backups
Overall Contribution
4/5
Perhaps it was just the hectic semester but I felt I put a good amount of effort into working on assignments passed to me, It may be a different thing altogether as to how much I was able to produce from this effort. And It’s hard to distinguish how much my work could influence the BIT Platform just yet, as I haven’t fully implemented / understood how powerful the CodeLingo workflow could be when integrated into the BIT Platform Pipeline. It has some great Potential, and I hope that in the advent I may pass project one I could continue to develop upon a proper tool-set for lecturers and students.
I thought my Xibo implementation and layouts where astatically pleasing
Producing Work that everyone gets to see
Exploring Xibo features
My Poster
Reflective Story
What a semester that has been… software engineering seemed to start off like a slap to the face, throwing most of what I knew about BIT papers out the window. When I was done with the last exam I told Adon “never again” his reply was “you’re not going to like project then” and like most things this semester, he was right, instead of a dainty slap I received a mental Batista bomb. Now I’m not saying that project one filled me with hatred (on the occasion) but it was one of the tougher papers I’ve had to slog through. But much like the quote from Albert Einstein “Adversity introduces a man to himself.” I feel I can take away a lot of valuable lessons now.
One of the hardest lessons I had to come to terms with after summarizing my semester was how much I could have actively done through the project to improve my environment and learning experience, to drown the reader in quotes I feel Teddy Roosevelt accurately portrays this when he said, “If you could kick the person in the pants responsible for most of your trouble, you wouldn't sit for a month.”
To start my semester in project one I had been assigned the task of implementing digital signage to service the display needs of the project room. This started out as research into free and open source digital signage solutions. This came back with Xibo which Lewis had already suggested, no surprises there, so it was off to start creating the initial VM, layouts and campaigns. Once I spun up a Xibo server at home and created the layouts I was quite proud! Threw in a few motivational quotes for good measure and it was ready for the project rooms viewing pleasure! Overall, I enjoyed my time messing with the Xibo CMS and had hoped to contribute to the open source project, that was, until, the following meeting that we had all been fearing (or at least just me) who would be tasked with the start-up company CodeLingo.
The meeting had begun and I had displayed my pride and joy Xibo to the congregation, with the assigned task complete and a body free to ponder another mystery, Adon glances at the board and finds a missing name next to CodeLingo. So, I was to be BIT Platforms Champion of Codelingo, no big deal how hard could it be? Hard. But it didn’t have to be. As I tried to implement the illusive CodeLingo server on the completely foreign op infrastructure there was always some small obstacle to overcome, sometimes I solved it post-haste sometimes I didn’t. I was working by myself, I felt secluded in my suffering, after all most problems that I encounter in life I could surly google to gain a few steps towards comprehension, but no this was completely virgin code, un googleable.
Most of my troubles related to the onprem solution on serval occasions where patched and fixed via a few updates released shortly after, I couldn’t have known that these problems weren’t originating from my side? It was a completely different environment?! But... that is no excuse, and I should have asked. The staff of CodeLingo where more than happy to answer my questions and besides, they write QUERY language for god sake! But even through all the frustration I was adamant to resolve problems I encountered.
Finally showcase day. Fortunately, when in dire need of assistance whilst still developing one of the final pieces of software (lingo builder) to display at showcase Adon in his wisdom tells me to swallow my pride and ask for the much-needed help, the helpful team at CodeLingo where right on hand to lend their knowledge and thus the showcase had somewhat of a demo.
In conclusion, there was a lot of anguish and despair strewn throughout, but these states of mental being where merely the result of ignorance. I aim to take these invaluable lessons with me into project two (should I pass) and strive to approach my prior work with more conviction and clarity.


File index
README.md app/assets/config/manifest.js app/assets/javascripts/application.js app/assets/javascripts/cable.js app/assets/stylesheets/application.css.scss app/assets/stylesheets/base.scss app/assets/stylesheets/test.scss app/channels/application_cable/channel.rb app/channels/application_cable/connection.rb app/controllers/application_controller.rb app/controllers/visitors_controller.rb app/helpers/application_helper.rb app/interactors/check_location_staleness.rb app/interactors/check_the_weather.rb app/interactors/handle_any_commands.rb app/interactors/inspect_message_validity.rb app/interactors/manage_message.rb app/interactors/petition_for_info.rb app/interactors/record_data_point.rb app/interactors/thank_the_user.rb app/interactors/update_user_location.rb app/interactors/verify_user.rb app/jobs/application_job.rb app/mailers/application_mailer.rb app/models/application_record.rb app/models/concerns/bot_utils.rb app/models/data_point.rb app/models/mara_bot.rb app/models/user.rb app/models/weather.rb lib/tasks/mara.rake lib/tasks/rdoc.rake lib/tasks/scheduler.rake


--- layout: page title: HW date: 2010-08-09 01:55:23.000000000 -04:00 categories: [] tags: [] status: publish type: page published: true meta: _edit_last: '2' _wp_page_template: default author: login: admin email<EMAIL_ADDRESS>display_name: truth first_name: '' last_name: '' ---
[catlist id=12]


Bazel JavaScript rules
Bazel is Google’s build system. It powers our development at large scale by caching intermediate build artifacts, allowing build and test to be incremental and massively parallelizable. Read more at https://bazel.build
This JavaScript support lets you build and test code that targets a JavaScript runtime, including NodeJS and browsers.
Scope of the project
This repository contains an orthogonal set of rules which covers an opinionated toolchain for JavaScript development. When requesting a new rule, describe your use case, why it’s important, and why you can’t do it with the existing rules. This is because we have limited resources to maintain additional rules.
The repository accepts contributions in terms of bug fixes or implementing new features in existing rules. If you’re planning to implement a new rule, please strongly consider opening a feature request first so the project’s maintainers can decide if it belongs to the scope of this project or not.
For rules outside of the scope of the projects we recommend hosting them in your GitHub account or the one of your organization.
Design
Most bazel rules include package management. That is, the WORKSPACE
file installs your dependencies as well as the toolchain. In some environments, this is the normal workflow, for example in Java, Gradle and Maven are each both a build tool and a package manager.
In nodejs, there are a variety of package managers and build tools which can interoperate. Also, there is a well-known package installation location (node_modules
directory in your project). Command-line and other tools look in this directory to find packages. So we must either download packages twice (risking version skew between them) or point all tools to Bazel’s external
directory with NODE_PATH
which would be very inconvenient.
Instead, our philosophy is: in the NodeJS ecosystem, Bazel is only a build tool. It is up to the user to install packages into their node_modules
directory, though the build tool can verify the contents.
Hermeticity and reproducibility
Bazel generally guarantees builds are correct with respect to their inputs. For example, this means that given the same source tree, you can re-build the same artifacts as an earlier release of your program. In the nodejs rules, Bazel is not the package manager, so some responsibility falls to the developer to avoid builds that use the wrong dependencies. This problem exists with any build system in the JavaScript ecosystem.
Both NPM and Yarn have a lockfile, which ensures that dependencies only change when the lockfile changes. Users are strongly encouraged to use the locking mechanism in their package manager.
References:
- npm: https://docs.npmjs.com/files/package-lock.json
- yarn: https://yarnpkg.com/lang/en/docs/yarn-lock/
Note that https://github.com/bazelbuild/rules_nodejs/issues/1 will take the guarantee further: by using the lockfile as an input to Bazel, the nodejs rules can verify the integrity of the dependencies. This would make it impossible for a build to be non-reproducible, so long as you have the same lockfile.
Quickstart
First we create a new workspace, which will be in a new directory.
We can use the @bazel/create
npm package to do this in one command.
This is the fastest way to get started for most use cases.
See the installation page for details and alternative methods.
$ npm init @bazel my_workspace
$ cd my_workspace
You could do the same thing with yarn:
$ yarn create @bazel my_workspace $ cd my_workspace
Both of these commands are equivalent to
npx @bazel/create
which downloads the latest version of the@bazel/create
package from npm and runs the program it contains. Run the tool with no arguments for command-line options and next steps.
Next we install some development tools. For this example, we’ll use Babel to transpile our JavaScript, Mocha for running tests, and http-server to serve our app. This is just an arbitrary choice, you probably already have some tools you prefer.
$ npm install @babel/core @babel/cli @babel/preset-env http-server mocha domino
Let’s run these tools with Bazel. There are two ways to run tools:
- Use an auto-generated Bazel rule by importing from an
index.bzl
file in the npm package - Use a custom rule in rules_nodejs or write one yourself
In this example we use the auto-generated rules. First we need to import them, using a load statement. So edit BUILD.bazel and add:
load("@npm//@babel/cli:index.bzl", "babel")
load("@npm//mocha:index.bzl", "mocha_test")
load("@npm//http-server:index.bzl", "http_server")
This shows us that rules_nodejs has told Bazel that a workspace named @npm is available (think of the at-sign like a scoped package for Bazel). rules_nodejs will add index.bzl files exposing all the binaries the package manager installed (the same as the content of the node_modules/.bin folder). The three tools we installed are in this @npm scope and each has an index file with a .bzl extension.
Next we teach Bazel how to transform our JavaScript inputs into transpiled outputs.
Here we assume that you have app.js
and es5.babelrc
in your project. See our example webapp for an example of what those files might look like.
Now we want Babel to produce app.es5.js
so we add to BUILD.bazel
:
babel(
name = "compile",
data = [
"app.js",
"es5.babelrc",
"@npm//@babel/preset-env",
],
outs = ["app.es5.js"],
args = [
"app.js",
"--config-file",
"./$(execpath es5.babelrc)",
"--out-file",
"$(execpath app.es5.js)",
],
)
This just calls the Babel CLI, so you can see their documentation for what arguments to pass. We use the $(execpath) helper in Bazel so we don’t need to hardcode paths to the inputs or outputs.
We can now build the application: npm run build
and we see the .js outputs from babel appear in the dist/bin
folder.
Let’s serve the app to see how it looks, by adding to BUILD.bazel
:
http_server(
name = "server",
data = [
"index.html",
"app.es5.js",
],
args = ["."],
)
Add a serve
entry to the scripts in package.json
:
{
"scripts": {
"serve": "ibazel run :server"
}
}
ibazel is the watch mode for bazel.
Note that on Windows, you need to pass
--enable_runfiles
flag to Bazel. That’s because Bazel creates a directory where inputs and outputs both appear together, for convenience.
Now we can serve the app: npm run serve
Finally we’ll add a test using Mocha, and the domino package so we don’t need a browser. Add to BUILD.bazel
:
mocha_test(
name = "unit_tests",
args = ["*.spec.js"],
data = glob(["*.spec.js"]) + [
"@npm//domino",
"app.es5.js",
],
)
Run the tests: npm test
Next steps
Look through the /examples
directory in this repo for many examples of running tools under Bazel.
You might want to look through the API docs for custom rules such as TypeScript, Rollup, and Terser which add support beyond what you get from calling the CLI of those tools.


Israel President asks Parliament to find PM
Else, polls will be held early next year.
by Agence France-PresseIsrael’s President Reuven Rivlin tasked Parliament on Thursday with finding a new Prime Minister, as he sought to avoid new elections after incumbent Benjamin Netanyahu and rival Benny Gantz each failed to form a government.
“Starting today and for 21 days, the decision of who to task with forming the government is in the hands of the members of the Knesset (parliament),” Mr. Rivlin said, a day after Mr. Gantz admitted he would be unable to build a governing coalition.
Parliament will now have until December 11 to find a candidate, who can command the support of the majority of the country’s 120 MPs or a new general election will be called for early 2020.
It would be the third such poll within 12 months.
“The disruptive politics must end,” Mr. Rivlin said, addressing MPs.