Advice Requested - CHDK Security Project - Object Detection and Steganography - page 2 - General Discussion and Assistance - CHDK Forum

Advice Requested - CHDK Security Project - Object Detection and Steganography

  • 33 Replies
  • 7677 Views
Advertisements
Thanks for the reply srsa_4c!

That's a bit unfortunate that CHDK doesn't have direct access to the JPEG creation/saving process. I'll see if I can use any of the hooks in filewrite.c, but I'm still not entirely clear on how they work. It seems the camera I'm using (A2500) has DryOS v2.3 (revision 52), so it might be saving the JPEG in multiple passes. Odd that the JPEG chunks are passed in different orders based on the file size.

I'll also try directly modifying the RAW image and seeing what makes it into the JPEG. My concern there is that much of the RAW data is lost when converting to a JPEG, so any information I embed will likely be lost as well.

Currently I'm writing a separate C program to get the framework laid out for the steganography, then I'll try and implement it into CHDK.

*

Offline reyalp

  • ******
  • 12145
I'll also try directly modifying the RAW image and seeing what makes it into the JPEG. My concern there is that much of the RAW data is lost when converting to a JPEG, so any information I embed will likely be lost as well.
If you want to modify the image data in filewrite, that will be very difficult since it's already jpeg compressed.
Don't forget what the H stands for.

I'll also try directly modifying the RAW image and seeing what makes it into the JPEG. My concern there is that much of the RAW data is lost when converting to a JPEG, so any information I embed will likely be lost as well.
If you want to modify the image data in filewrite, that will be very difficult since it's already jpeg compressed.

Does it matter that it's already JPEG compressed? Given that I want to embed time/date information in the photo (i.e. by modifying the LSB to contain the data), it seems that doing this on already compressed data would be preferable. Then my work won't be lost to compression, correct?

Is it possible to actually modify the image data in filewrite.c? It seems like it might be by modifying the values pointed to by the addr pointer in various chunks, but I'm not sure how you could get reliable position information for later decoding of the embedded information.

My current strategy is to start from the end of the JPEG image and work backwards (skipping the 0xFF 0xD9 bytes at the end of the image), to ensure that I don't overwrite any header information at the start of the file. I'm noticing that I need to watch out for other markers in the data however, such as (0xFF 0x00), which attempts to mark 0xFF as a non-marker byte.
« Last Edit: 05 / March / 2014, 02:17:24 by Vegetothe1st »

*

Offline reyalp

  • ******
  • 12145
Does it matter that it's already JPEG compressed? Given that I want to embed time/date information in the photo (i.e. by modifying the LSB to contain the data), it seems that doing this on already compressed data would be preferable. Then my work won't be lost to compression, correct?
If you fiddle with random bits in the compressed data, I would expect it to stop being a valid jpeg. Maybe that's ok in your application.
Quote
Is it possible to actually modify the image data in filewrite.c? It seems like it might be by modifying the values pointed to by the addr pointer in various chunks, but I'm not sure how you could get reliable position information for later decoding of the embedded information.
Filewrite gives you enough information to know the position within the file and the size of the chunk you are working with.
Don't forget what the H stands for.


Does it matter that it's already JPEG compressed? Given that I want to embed time/date information in the photo (i.e. by modifying the LSB to contain the data), it seems that doing this on already compressed data would be preferable. Then my work won't be lost to compression, correct?
If you fiddle with random bits in the compressed data, I would expect it to stop being a valid jpeg. Maybe that's ok in your application.
Quote
Is it possible to actually modify the image data in filewrite.c? It seems like it might be by modifying the values pointed to by the addr pointer in various chunks, but I'm not sure how you could get reliable position information for later decoding of the embedded information.
Filewrite gives you enough information to know the position within the file and the size of the chunk you are working with.

How the data is presented in filewrite.c is the same as how it's seen when you open the JPEG in a hex editor, correct? I was going to try and create some logging files later today to ensure this was the case. If true, then I should be able to modify the bytes as long as I'm careful to avoid messing with the JPEG markers. I've noticed that overwriting any of these does make it an invalid JPEG and it can't be opened by an image viewer. I would like it to stay openable. :)

Ideally I'd want to modify only the data in the last chunk (assuming it's not the Exif headers as was mentioned before), so that when decoding the message in the JPEG I know I can just start from the end and work backwards. Encoding elsewhere in the image (say in the third chunk rather than the last) may give me an offset from the start of the JPEG, but I wouldn't have any way of knowing this offset when trying to decode.

Do you know if there are any minimum chunk sizes? Could be an issue if I'm waiting to see the last chunk and it only turns out to be a few bytes when I need a lot more.

*

Offline philmoz

  • *****
  • 3128
    • Photos
Does it matter that it's already JPEG compressed? Given that I want to embed time/date information in the photo (i.e. by modifying the LSB to contain the data), it seems that doing this on already compressed data would be preferable. Then my work won't be lost to compression, correct?
If you fiddle with random bits in the compressed data, I would expect it to stop being a valid jpeg. Maybe that's ok in your application.
Quote
Is it possible to actually modify the image data in filewrite.c? It seems like it might be by modifying the values pointed to by the addr pointer in various chunks, but I'm not sure how you could get reliable position information for later decoding of the embedded information.
Filewrite gives you enough information to know the position within the file and the size of the chunk you are working with.

How the data is presented in filewrite.c is the same as how it's seen when you open the JPEG in a hex editor, correct? I was going to try and create some logging files later today to ensure this was the case. If true, then I should be able to modify the bytes as long as I'm careful to avoid messing with the JPEG markers. I've noticed that overwriting any of these does make it an invalid JPEG and it can't be opened by an image viewer. I would like it to stay openable. :)

Ideally I'd want to modify only the data in the last chunk (assuming it's not the Exif headers as was mentioned before), so that when decoding the message in the JPEG I know I can just start from the end and work backwards. Encoding elsewhere in the image (say in the third chunk rather than the last) may give me an offset from the start of the JPEG, but I wouldn't have any way of knowing this offset when trying to decode.

Do you know if there are any minimum chunk sizes? Could be an issue if I'm waiting to see the last chunk and it only turns out to be a few bytes when I need a lot more.

I thought you wanted to add the data as a hidden watermark to the image pixel data?

If this is the case then you won't be able to do this by modifying the JPEG file data. The RAW image data is converted to YCbCr colour space (often with  4:1:1 encoding), split into 8x8 pixel chunks each of which undergoes a discrete cosine transform (DCT) from which the least visible information is discarded. The data is then compressed again using a lossless huffman encoding compression.

If you change the LSB of this JPEG compressed data it will most likely invalidate the data stream and the decompression of the image will fail when you try and view it.

In order to modify the LSB of a single pixel you would have to uncompress the JPEG data, make the change and then recompress it, while keeping the file size identical unless you also update the file headers.

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)

After some testing, it appears I can see all of the JPEG data using jpeg_chunks->address; apparently the data all seems to fit in a single chunk every time. Now I need to try modifying some of it.

Addressing the concerns above, I've been messing around with modifying the LSBs to encode the data and it is very easy to mess the JPEG up such that it becomes a corrupted image. It's definitely possible to change a few bytes and have the image be perfectly valid though, at least from my testing on standalone JPEG images that I've loaded and changed. I've yet to try modifying the data seen in the filewrite_main_hook, but it looks to be the same as the data I've already been messing with (starts with FFD8, ends with FFD9 as JPEGs should).

I'm just trying to encode date/time information into the image at the moment (if I said watermarking this is what I meant). This is doable by converting the information to a binary representation and then changing the LSB of a byte in the image to the value of a single bit in the message. This means I need to change 1 byte in the image for every bit in my message.

-----

On a different note, I'm noticing that occasionally during my testing the camera just turns off after taking a picture. I'm doing some long-running tasks for testing (converting the binary data to hex and printing it to a file), is this causing the camera to think it failed to take a picture and shut off? The LiveView shows the image and then proceeds back to live tracking, but the camera just shuts off after a few seconds of processing. Preventable by only printing a few thousand hex bytes rather than the whole image, so I'm assuming this is the case.
« Last Edit: 06 / March / 2014, 02:02:35 by Vegetothe1st »

And directly modifying the bytes being pointed to works!  :D

Time to finalize the steganography algorithm and get it implemented.

Slightly off the topic of CHDK, but does anybody know of any easy-to-use encryption libraries that I could integrate with CHDK? Might as well encrypt the embedded information as well. I tried getting both NaCl and Sodium to work, but wasn't able to; NaCl refused to compile at all, and I couldn't link a test program against Sodium for some reason despite the libraries being in /usr/local/lib. The latter issue might be a problem with my Ubuntu configuration, I can't seem to link against any libraries in that folder.


*

Offline reyalp

  • ******
  • 12145
It's definitely possible to change a few bytes and have the image be perfectly valid though, at least from my testing on standalone JPEG images that I've loaded and changed.
Like Phil, I'm having trouble seeing why this would be true in the general case. Unless you've actually worked out how it affects compressed data and determined the result will always be valid, just having a few examples that aren't completely broken doesn't mean much.
Quote
On a different note, I'm noticing that occasionally during my testing the camera just turns off after taking a picture.
A first step would be to get a romlog: http://chdk.wikia.com/wiki/Debugging#Camera_crash_logs_.28romlog.29

Quote
Slightly off the topic of CHDK, but does anybody know of any easy-to-use encryption libraries that I could integrate with CHDK?
I don't know of any specifically, but given that CHDK doesn't have access to a full ANSI C library your best bet will be something light with minimal dependencies.
Don't forget what the H stands for.

Quote
Like Phil, I'm having trouble seeing why this would be true in the general case. Unless you've actually worked out how it affects compressed data and determined the result will always be valid, just having a few examples that aren't completely broken doesn't mean much.

I'll hopefully know if my method will work tomorrow or Friday, I'll keep updating the thread. I'm not sure why it wouldn't work, the data present in filewrite_main_hook() is seemingly the exact same data that you would get when opening the JPEG in a hex editor. Again, I just need to ensure that I avoid modifying header information and other significant byte sequences (such as FF00 sequences that indicate the FF byte isn't a header).

Quote
A first step would be to get a romlog: http://chdk.wikia.com/wiki/Debugging#Camera_crash_logs_.28romlog.29

Thanks for that, I probably should have looked at the Debugging article more closely. I'll try and use these the next time the camera bugs out on me.

Quote
I don't know of any specifically, but given that CHDK doesn't have access to a full ANSI C library your best bet will be something light with minimal dependencies.

Good point, I'll need to make sure any solution I choose is pretty lightweight. I'll keep looking around, ideally I want an asymmetric algorithm so I could hard code the public key in the firmware and keep the other key private.

It might be possible just to write my own functions to implement RSA, it just never seems to be a good idea to try and do encryption yourself though when well-tested solutions exist.
« Last Edit: 06 / March / 2014, 03:46:16 by Vegetothe1st »

 

Related Topics