Skip to content

Instantly share code, notes, and snippets.

@h4k1m0u
Created August 15, 2024 16:10
Show Gist options
  • Save h4k1m0u/f217fe174a629163f93a8c95371df37e to your computer and use it in GitHub Desktop.
Save h4k1m0u/f217fe174a629163f93a8c95371df37e to your computer and use it in GitHub Desktop.
Use steganography to read/write a textual password from/to sequential pixels' least-significant bits
#include <limits.h>
#include <string.h>
#include <stdbool.h>
#include <gd.h>
#include "utils.h"
/**
* Print password written beforehand on image with steganography_write.c
* - GD documentation: https://libgd.github.io/manuals/2.1.1/files/preamble-txt.html
*
* How to build & run:
* $ gcc -lgd utils.c steganography_read.c -o steganography_read
* $ ./steganography image.png
*/
int main(int argc, char** argv) {
if (argc != 2) {
printf("USAGE: %s IMAGE\n", argv[0]);
return 1;
}
const char* filename = argv[1];
// input png image
FILE* file = fopen(filename, "rb");
if (file == NULL) {
perror("Error");
return 1;
}
gdImagePtr image = gdImageCreateFromPng(file);
const int WIDTH = image->sx;
const int HEIGHT = image->sy;
printf("w: %d, h: %d\n", WIDTH, HEIGHT);
int x = 0;
int y = 0;
size_t i_c = 0;
char password[100];
// read password characters from image
while (true) {
// each password character spans 8 pixel
char c = 0;
for (size_t i_b = 0; i_b < CHAR_BIT; i_b++) {
int value = gdImageGetTrueColorPixel(image, x, y);
bool bit = value & 1;
c += bit << i_b;
move_to_next_pixel(&x, &y, WIDTH);
} // END BITS
password[i_c++] = c;
// null terminator character reached
if (c == 0)
break;
}
printf("Password: %s\n", password);
// free assets
fclose(file);
gdImageDestroy(image);
return 0;
}
#include <limits.h>
#include <string.h>
#include <stdbool.h>
#include <gd.h>
#include "utils.h"
/**
* Write given password on image, starting from pixel (0, 0) & proceeding row by row
* Each password's bit is written to the least-significant bit of the rgb value of each pixel
* The password is terminated with a null character ('\0')
* - GD documentation: https://libgd.github.io/manuals/2.1.1/files/preamble-txt.html
*
* How to build & run:
* $ gcc -lgd utils.c steganography_write.c -o steganography_write
* $ ./steganography image_in.png "my password" image_out.png
*/
int main(int argc, char** argv) {
if (argc != 4) {
printf("USAGE: %s IMAGE_IN PASSWORD IMAGE_OUT\n", argv[0]);
return 1;
}
const char* filename_in = argv[1];
const char* password = argv[2];
const char* filename_out = argv[3];
// input png image
FILE* file_in = fopen(filename_in, "rb");
if (file_in == NULL) {
perror("Error");
return 1;
}
gdImagePtr image = gdImageCreateFromPng(file_in);
const int WIDTH = image->sx;
const int HEIGHT = image->sy;
printf("w: %d, h: %d\n", WIDTH, HEIGHT);
int x = 0;
int y = 0;
// write password characters to image
printf("\nWriting password characters...\n");
for (size_t i_c = 0; i_c < strlen(password); i_c++) {
char c = password[i_c];
printf("\n- c: %c %d - ", c, c);
for (size_t i_b = 0; i_b < CHAR_BIT; i_b++) {
bool bit = (c >> i_b) & 1;
printf(bit ? "1" : "0");
int value = gdImageGetTrueColorPixel(image, x, y);
// set or clear least-significant bit
if (bit)
value |= 1;
else
value &= ~1;
gdImageSetPixel(image, x, y, value);
move_to_next_pixel(&x, &y, WIDTH);
} // END BITS
} // END CHARACTERS
// write null terminator
printf("\nWriting null terminator...\n");
printf("Unsetting from pixel (%d, %d)...\n", x, y);
for (size_t i_b = 0; i_b < CHAR_BIT; i_b++) {
int value = gdImageGetTrueColorPixel(image, x, y);
value &= ~1;
gdImageSetPixel(image, x, y, value);
move_to_next_pixel(&x, &y, WIDTH);
}
// output png image
FILE* file_out = fopen(filename_out, "wb");
gdImagePng(image, file_out);
// free assets
fclose(file_out);
fclose(file_in);
gdImageDestroy(image);
return 0;
}
#include "utils.h"
void move_to_next_pixel(int* x, int* y, int width) {
*x += 1;
if (*x == width) {
*x = 0;
*y += 1;
}
}
#ifndef UTILS_HPP
#define UTILS_HPP
void move_to_next_pixel(int* x, int* y, int width);
#endif // UTILS_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment