flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2 |
Author |
|
Madis731 13 Apr 2009, 07:46
Yeah, I assembled a "decryptor" to the sample image in Wiki
![]() Just pass it the original image and it will output the other in a few seconds: Code: format binary as "bmp" file 'StenographyOriginal.bmp':0,54 repeat 120000 virtual at 0 file 'StenographyOriginal.bmp':%+53,1 load char from 0 end virtual char=(char and 011b)*64 db char end repeat ![]() EDIT: You have a bug in the first code. You don't use ECX anywhere! Here, I've fixed it for you: Code: ;The stall only happens when you do this: ; mov al,12h ; mov eax,1234h ;but not when you access *only* al! ;The simplest code would be: mov ecx,0x36 ; sizeof(BITMAPINFOHEADER) headerFill: mov al,[pMemOrig+ecx] mov [bmpOriginal+ecx],al mov al,[pMemAdd+ecx] mov [bmpAdd+ecx],al loop headerFill ;Another try mov ecx,0x36 and 0xFC ; sizeof(BITMAPINFOHEADER) headerFill: sub ecx,4 jc .loop_tail mov eax,[pMemOrig+ecx] mov [bmpOriginal+ecx],eax mov eax,[pMemAdd+ecx] mov [bmpAdd+ecx],eax jmp headerFill .loop_tail: mov ecx,0x34 mov ax,[pMemOrig+ecx] mov [bmpOriginal+ecx],ax mov ax,[pMemAdd+ecx] mov [bmpAdd+ecx],ax And hey, look what my compiler did ![]() Btw, this is your (54-byte) header-copying part if you didn't recognize Code: $B2$24: ; Preds $B2$23 mov rdx, QWORD PTR [rsi] ;25.5 mov QWORD PTR [rcx], rdx ;25.5 mov r8, QWORD PTR [rsi+8] ;25.5 mov QWORD PTR [rcx+8], r8 ;25.5 mov r9, QWORD PTR [rsi+16] ;25.5 mov QWORD PTR [rcx+16], r9 ;25.5 mov r10, QWORD PTR [rsi+24] ;25.5 mov QWORD PTR [rcx+24], r10 ;25.5 mov r11, QWORD PTR [rsi+32] ;25.5 mov QWORD PTR [rcx+32], r11 ;25.5 mov rdx, QWORD PTR [rsi+40] ;25.5 mov QWORD PTR [rcx+40], rdx ;25.5 mov edx, DWORD PTR [rsi+48] ;25.5 mov DWORD PTR [rcx+48], edx ;25.5 movzx edx, WORD PTR [rsi+52] ;25.5 mov WORD PTR [rcx+52], dx ;25.5 I would argue that this isn't the most optimal, but it is the fastest ![]() Last edited by Madis731 on 13 Apr 2009, 09:38; edited 2 times in total |
|||
![]() |
|
pal 13 Apr 2009, 08:35
Thats just annoying that my code is hella long compared to yours <_< (I use all Windows APIs etc.). Nice example though.
Any ideas about the structure copying thing? |
|||
![]() |
|
Madis731 13 Apr 2009, 09:08
(Now that I've understood Stenograhy) I just realized that your algorithm loop should be something like:
Code: for i=0 to size step4 DWORD dst_img[i] = (src_img[i] & 0xFEFEFEFE) | (add_img[i] & 0x01010101) next You shouldn't need anything fancier ![]() Code: ;ESI=src ;EDI=dst ;EBP=add mov ecx,[size] @@: mov eax,[esi] and eax,0xFEFEFEFE mov ebx,[ebp] and ebx,0x01010101 or eax,ebx mov [edi],eax sub ecx,4 jnc @b ...and we're done ![]() EDIT: I know I shouldn't optimize it that much, but I love it so here's a smaller and faster variant: Code: mov eax,[esi] mov ebx,[ebp] xor ebx,eax ;Find differences and ebx,0x01010101 ;take only one bit per byte xor eax,ebx ; update the bytes mov [edi],eax Try this site for even wilder algorithms: http://www.jjj.de/fxt/ It was renamed from "Algorithms for Programmers" to "Matters Computational" some time ago. There's a huge (5MB) pdf there. Samples are in C |
|||
![]() |
|
pal 13 Apr 2009, 15:33
Cheers for all the help man! I aint got it working, but I can see that your code will work. I just cant get the header bit working (the code works, but I think its something to do with reading the file earlier on as it ends up that in the header copy loop pMemAdd is only like 4 more than pMemOrig, which is obviously incorrect).
I think I need to work a bit more in ASM if I cant do simple tasks like this -.- Somone ort to slap me. (How long was it before you were good at ASM?) Actually, just looking at the pseudo-code, that is incorrect as that will mean each bit will be stored in the corresponding bit on the original image, whilst it should be the corresponding byte. I looked at that link. Damn that is really useful, nice codes and the PDF. Tyvm. |
|||
![]() |
|
Madis731 14 Apr 2009, 06:07
Maybe I did things differently and I didn't understand your bit-wizardry
![]() I took my algorithm from the Wikipedia where each byte corresponds to another byte and the images are of same size. What I can see from your code posted here, you are trying to fit all the significant bits in the larger image and if you use only one bit, then you need to have the "hidden" image be 8 times smaller. ![]() I had this "cat-image" stored as low two significant bits, so it was really easy to "and" and "or" these two pictures. In your case I think I'll need to revisit this topic later. Sorry if I have mislead you. Btw, I've done ASM about 5 years now and still learning. There might be some wonder-persons who got a grasp on ASM after a few weeks, but for me it took at least a year or so - maybe because I'm lazy. You can be thankful that the FASM-community has been ever-increasing so the learning-curve is not so bad! |
|||
![]() |
|
pal 14 Apr 2009, 08:54
Ahh I see yeah. Thats why steganography is good, there are a wide range of methods that can be used. Yeah I can see how your code works now. I think using bt* will work in my case, I just need to get the header filling in working properly, but yeah more reading first! Its cool about misleading me
![]() I am thinking of doing what the UK did in WWI (or WWII <- think it was that one). The Germans were intercepting UK-USA communication, so we added white noise to the recordings. Apparently without pretty much an identical white noise sound, you cannot extract the original recording. Once my exams are over its gonna be ASM and C pretty much all the way, need to get the languages down. By the way, here is my full bitmap steganographier: Code: #include <stdio.h> #include <stdlib.h> #include <string.h> #define BMAGIC 0x4d42 typedef unsigned char byte; typedef unsigned short word; typedef unsigned long dword; typedef struct { word biType; dword biFileSize; word biReserved1; word biReserved2; dword biDataOffset; dword biInfoSize; dword biWidth; dword biHeight; word biPlanes; word biBitCount; dword biCompression; dword biSizeImage; dword biXPelsPerMeter; dword biYPelsPerMeter; dword biClrUsed; dword biClrImportant; } __attribute__ ((packed)) BITMAPHEADERINFO; int ExtractBitmap(char* szBitmap, char* szOutput, long lWidth, long lHeight, long lBitsPerPix); int AddBitmap(char* szOriginal, char* szAdd, char* szOutput); int ExtractBitmap(char* szBitmap, char* szOutput, long lWidth, long lHeight, long lBitsPerPix) { FILE *pBitmap = fopen(szBitmap,"rb"); if(pBitmap == NULL) return 0; long lRes = 0; fseek(pBitmap,0,SEEK_END); long lBitSize = ftell(pBitmap); fseek(pBitmap,0,SEEK_SET); char *szBitCont = (char*)malloc(lBitSize); if(szBitCont != NULL) { if(fread(szBitCont,1,lBitSize,pBitmap) == lBitSize) { BITMAPHEADERINFO bmpBitmap; memset(&bmpBitmap,0,sizeof(BITMAPHEADERINFO)); memcpy(&bmpBitmap,szBitCont,sizeof(BITMAPHEADERINFO)); long lOutSize = (lWidth * lHeight * (lBitsPerPix / 8)); if((lBitSize - bmpBitmap.biDataOffset) >= lOutSize) { FILE *pOutput = fopen(szOutput,"wb"); if(pOutput != NULL) { BITMAPHEADERINFO bmpOutput; memset(&bmpOutput,0,sizeof(BITMAPHEADERINFO)); bmpOutput.biType = BMAGIC; bmpOutput.biFileSize = (lWidth * lHeight * (lBitsPerPix / 3)) + sizeof(BITMAPHEADERINFO); bmpOutput.biDataOffset = sizeof(BITMAPHEADERINFO); bmpOutput.biInfoSize = 40; bmpOutput.biWidth = lWidth; bmpOutput.biHeight = lHeight; bmpOutput.biPlanes = 1; bmpOutput.biBitCount = lBitsPerPix; bmpOutput.biSizeImage = lOutSize; char *szOutCont = (char*)calloc(lOutSize,1); if(szOutCont != NULL) { unsigned long i = bmpBitmap.biDataOffset, x = 0, lShift; for(; i < lBitSize && x < lOutSize && (lShift = If you are interested... ^^ |
|||
![]() |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.