Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Apt debian packages #2541

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libcapstone-dev/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.deb
*.txt
61 changes: 61 additions & 0 deletions libcapstone-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
ARG VERSION=""
ARG LIBCAPSTONE_NAME=""

# Assume this is run from capstone/debian directory
# Run in the root of the repo
# docker build -f ./debian/Dockerfile -t packager .
FROM debian:bookworm-slim

# Install necessary tools for packaging
RUN apt-get -qq update && \
DEBIAN_FRONTEND=noninteractive apt-get -qq install -y \
fakeroot dpkg-dev dos2unix cmake

# Copy your project files into the container
RUN mkdir /capstone
COPY . /capstone
WORKDIR /capstone/

# Using cmake, see BUILDING.md file
# For debug build change "Release" to "Debug"
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_SHARED_LIBS=1
RUN cmake --build build

# List files before cmake install
# RUN find / -type f > /before-install.txt

# Run cmake install, by default everything goes into /usr/local
RUN cmake --install build

# List files after cmake install
# RUN find / -type f > /after-install.txt

# Make directories as needed
RUN mkdir -p /package-root/usr/include/capstone/
RUN mkdir -p /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/
RUN mkdir -p /package-root/usr/share/doc/libcapstone-dev/

# Copy /usr/local/include/capstone/ to /package-root/usr/local/include/capstone/ and all other cases
RUN cp -r /usr/local/include/capstone/* /package-root/usr/include/capstone/
RUN cp -r /usr/local/lib/pkgconfig/capstone* /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/
RUN cp -r /usr/local/lib/libcapstone.a /package-root/usr/lib/x86_64-linux-gnu/
# Need libcapstone.a too

# Create DEBIAN directory and control file
COPY ./libcapstone-dev/control /package-root/DEBIAN/control

# Update capstone.pc file with the correct version and remove archs field
# Update control file with the correct version
# TODO, I think pkgconfig needs to point from /usr/local to /usr?
ARG VERSION
ARG LIBCAPSTONE_NAME
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/DEBIAN/control
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc
RUN sed -i "s/Depends: <libcapstone-name> (= <version-placeholder>)/Depends: ${LIBCAPSTONE_NAME} (= ${VERSION})/" /package-root/DEBIAN/control
RUN sed -i "/^archs=/d" /package-root/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc

# Build the package
RUN fakeroot dpkg-deb --build /package-root /libcapstone-dev.deb

# The user can now extract the .deb file from the container with something like
# docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.deb /out"
59 changes: 59 additions & 0 deletions libcapstone-dev/check_capstone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

# Usage: ./check_capstone_pc.sh <path_to_deb_file> <expected_version>

DEB_FILE=$1
EXPECTED_VERSION=$2

# Check if the deb file exists
if [[ ! -f "$DEB_FILE" ]]; then
echo "Debian package file not found!"
exit 1
fi

# Create a temporary directory to extract the deb file
TEMP_DIR=$(mktemp -d)

# Extract the deb file
dpkg-deb -x "$DEB_FILE" "$TEMP_DIR"

# Remove leading 'v' if present, e. g. v1.5.1 -> 1.5.1
if [[ "$EXPECTED_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
EXPECTED_VERSION=${EXPECTED_VERSION:1}
fi

# Check if the version follows the format X.Y.Z, e. g. 1.5.1 or 1.9.1
if [[ ! "$EXPECTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version must be in the format X.Y.Z"
exit 1
fi

# Path to the capstone.pc file
CAPSTONE_PC="$TEMP_DIR/usr/lib/x86_64-linux-gnu/pkgconfig/capstone.pc"

# Check if the capstone.pc file exists
if [[ ! -f "$CAPSTONE_PC" ]]; then
echo "capstone.pc file not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

# Check the version in the capstone.pc file
ACTUAL_VERSION=$(grep "^Version:" "$CAPSTONE_PC" | awk '{print $2}')
if [[ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]]; then
echo "Version mismatch! Expected: $EXPECTED_VERSION, Found: $ACTUAL_VERSION"
rm -rf "$TEMP_DIR"
exit 1
fi

# Check if libcapstone.a is included in the package
LIBCAPSTONE_A="$TEMP_DIR/usr/lib/x86_64-linux-gnu/libcapstone.a"
if [[ ! -f "$LIBCAPSTONE_A" ]]; then
echo "libcapstone.a not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

echo "libcapstone-dev.deb file is correct."
rm -rf "$TEMP_DIR"
exit 0
20 changes: 20 additions & 0 deletions libcapstone-dev/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Package: libcapstone-dev
Version: <version-placeholder>
Architecture: amd64
Priority: optional
Section: universe/libdevel
Source: capstone
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Security Tools <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 8255 kB
Depends: <libcapstone-name> (= <version-placeholder>)
Homepage: https://www.capstone-engine.org/
Download-Size: 795 kB
APT-Sources: http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
Description: lightweight multi-architecture disassembly framework - devel files
Capstone is a lightweight multi-platform, multi-architecture disassembly
framework.
.
These are the development headers and libraries.
58 changes: 58 additions & 0 deletions libcapstone-dev/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# !/bin/bash
set -eu

# Function to get the current Ubuntu version
get_os_version() {
lsb_release -i -s 2>/dev/null
}

# Check if the script is running in the ./debian folder
if [[ $(basename "$PWD") != "libcapstone-dev" ]]; then
echo "ERROR: Script must be run from the ./libcapstone-dev directory"
exit 1
fi

OS_VERSION=$(get_os_version)
if [[ "$OS_VERSION" != "Ubuntu" && "$OS_VERSION" != "Debian" ]]; then
echo "ERROR: OS is not Ubuntu or Debian and unsupported"
exit 1
fi

# Get the version number as an input
# Check if version argument is provided
if [[ $# -ne 1 ]]; then
echo "ERROR: Version argument is required"
exit 1
fi

# Get the version number as an input
version=$1

# Remove leading 'v' if present, e. g. v1.5.1 -> 1.5.1
if [[ "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
version=${version:1}
fi

# Check if the version follows the format X.Y.Z, e. g. 1.5.1 or 1.9.1
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version must be in the format X.Y.Z"
exit 1
fi

# Extract the major version
major_version=$(echo "$version" | cut -d. -f1)
# Create the variable with the major version
libcapstone_name="libcapstone${major_version}"

# Now build the packager container from that
pushd ../
docker build -f ./libcapstone-dev/Dockerfile -t packager --build-arg VERSION="${version}" --build-arg LIBCAPSTONE_NAME="${libcapstone_name}" .
popd

# Copy deb file out of container to host
docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.deb /out"

# Check which files existed before and after 'make install' was executed.
# docker run --rm -v $(pwd):/out packager bash -c "cp /before-install.txt /out"
# docker run --rm -v $(pwd):/out packager bash -c "cp /after-install.txt /out"
# diff before-install.txt after-install.txt
2 changes: 2 additions & 0 deletions libcapstone/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.deb
*.txt
64 changes: 64 additions & 0 deletions libcapstone/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
ARG VERSION=""
ARG LIBCAPSTONE_NAME=""

# Assume this is run from capstone/debian directory
# Run in the root of the repo
# docker build -f ./debian/Dockerfile -t packager .
FROM debian:bookworm-slim

# Install necessary tools for packaging
RUN apt-get -qq update && \
DEBIAN_FRONTEND=noninteractive apt-get -qq install -y \
fakeroot dpkg-dev dos2unix cmake

# Copy your project files into the container
RUN mkdir /capstone
COPY . /capstone
WORKDIR /capstone/

# Using cmake, see BUILDING.md file
# For debug build change "Release" to "Debug"
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release -DCAPSTONE_BUILD_SHARED_LIBS=1
RUN cmake --build build

# List files before cmake install
RUN find / -type f > /before-install.txt

# Run cmake install, by default everything goes into /usr/local
RUN cmake --install build

# List files after cmake install
RUN find / -type f > /after-install.txt

# Make directories as needed
ARG LIBCAPSTONE_NAME
RUN mkdir -p /package-root/usr/lib/x86_64-linux-gnu/
RUN mkdir -p /package-root/usr/share/doc/${LIBCAPSTONE_NAME}

# TODO: at the moment, I get /usr/local/lib/libcapstone.so.6.0
# My question is, where is the .so.6.0 being populated? Should a fix be made to only have a .5, .6, etc?
# With that said, I will have to assume the version based as an argument is correct in populating the control file

# Copy files to the package root
RUN cp -r /usr/local/lib/libcapstone.so* /package-root/usr/lib/x86_64-linux-gnu/
# RUN cp /usr/share/doc/${LIBCAPSTONE_NAME}

# Create DEBIAN directory and control file
COPY ./libcapstone/control /package-root/DEBIAN/control

# Update capstone.pc file with the correct version and remove archs field
# Update control file with the correct version
ARG VERSION
ARG LIBCAPSTONE_NAME
RUN sed -i "s/^Version:.*/Version: ${VERSION}/" /package-root/DEBIAN/control
RUN sed -i "s/Package: libcapstone<major-version-placeholder>/Package: ${LIBCAPSTONE_NAME}/" /package-root/DEBIAN/control

# Add postinst script to run ldconfig after installation
COPY ./debian/postinst /package-root/DEBIAN/postinst
RUN chmod 755 /package-root/DEBIAN/postinst

# Build the package
RUN fakeroot dpkg-deb --build /package-root /${LIBCAPSTONE_NAME}.deb

# The user can now extract the .deb file from the container with something like
# docker run --rm -v $(pwd):/out packager bash -c "cp /libcapstone-dev.deb /out"
46 changes: 46 additions & 0 deletions libcapstone/check_capstone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

# Usage: ./check_capstone_pc.sh <path_to_deb_file> <expected_version>

DEB_FILE=$1
EXPECTED_VERSION=$2

# Check if the deb file exists
if [[ ! -f "$DEB_FILE" ]]; then
echo "Debian package file not found!"
exit 1
fi

# Create a temporary directory to extract the deb file
TEMP_DIR=$(mktemp -d)

# Extract the deb file
dpkg-deb -x "$DEB_FILE" "$TEMP_DIR"

# Remove leading 'v' if present, e. g. v1.5.1 -> 1.5.1
if [[ "$EXPECTED_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
EXPECTED_VERSION=${EXPECTED_VERSION:1}
fi

# Check if the version follows the format X.Y.Z, e. g. 1.5.1 or 1.9.1
if [[ ! "$EXPECTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version must be in the format X.Y.Z"
exit 1
fi

# Extract the major version
major_version=$(echo "$EXPECTED_VERSION" | cut -d. -f1)
# Create the variable with the major version
libcapstone_name="libcapstone${major_version}"

# Check if libcapstone.so is included in the package
LIBCAPSTONE_SO="$TEMP_DIR/usr/lib/x86_64-linux-gnu/${libcapstone_name}.so"
if [[ ! -f "$LIBCAPSTONE_SO" ]]; then
echo "${libcapstone_name}.so not found in the package!"
rm -rf "$TEMP_DIR"
exit 1
fi

echo "${libcapstone_name}.deb file is correct."
rm -rf "$TEMP_DIR"
exit 0
34 changes: 34 additions & 0 deletions libcapstone/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Package: libcapstone<major-version-placeholder>
Version: <version-placeholder>
Architecture: amd64
Priority: optional
Section: universe/libs
Source: capstone
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Security Tools <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 6623 kB
Depends: libc6 (>= 2.14)
Homepage: https://www.capstone-engine.org/
Download-Size: 664 kB
APT-Sources: http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
Description: lightweight multi-architecture disassembly framework - library
Capstone is a lightweight multi-platform, multi-architecture disassembly
framework.
.
Features:
- Support hardware architectures: ARM, ARM64 (aka ARMv8), Mips, PowerPC &
Intel.
- Clean/simple/lightweight/intuitive architecture-neutral API.
- Provide details on disassembled instructions (called "decomposer" by some
others).
- Provide some semantics of the disassembled instruction, such as list of
implicit registers read & written.
- Implemented in pure C language, with bindings for Java, OCaml and Python
ready to use and Ruby, C#, GO & Vala available on git repos.
- Native support for Windows & *nix (with OS X, Linux, *BSD & Solaris
confirmed).
- Thread-safe by design.
- Special support for embedding into firmware or OS kernel.
- Distributed under the open source BSD license.
6 changes: 6 additions & 0 deletions libcapstone/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
# postinst script for capstone package
set -e

# Update the shared library cache
ldconfig
Loading
Loading