Zlib decompression c++ - c++

I'm working with zlib and have some problem with decompression. I try to decompress packets that come to my program, but only the first packet is decompessed correctly. For example :
//first compressed packet
78 5e 72 65 60 08 65 bf cd c0 60 28 98 3f 95 03
08 18 19 19 25 18 4c af b9 32 38 0a a4 d6 6c 6d
6c 60 60 04 42 20 60 31 2b c9 37 61 c9 2c 28 33
e3 cc cd 4c 2e ca 2f ce 4f 2b 61 4e ce cf 65 00
29 38 c0 03 51 c6 7c 9b 81 e5 40 44 32 23 00
//first decompressed packet
//inflate return 0
45 00 00 55 07 db 00 00 31 11 6f 95 08 08 08 08
01 01 01 18 00 35 d6 45 00 41 10 65 7c b5 81 80
00 01 00 01 00 00 00 00 04 36 74 6f 34 04 69 70
76 36 09 6d 69 63 72 6f 73 6f 66 74 03 63 6f 6d
00 00 01 00 01 c0 0c 00 01 00 01 00 00 03 db 00
04 c0 58 63 01
But when i try to decompress second packet "inflate" function return me -3 and decompress nothing. Example for second compressed packet :
//second compressed packet
//inflate return -3
72 65 60 f0 62 bf 03 36 74 3e c2 d0 77 cb 19 cc
de cc d8 18 8c 30 94 b9 20 b1 92 35 33 bf 38 b1
84 a9 a8 14 c5 24 17 2f 06 96 88 63 e7 ad 01 00
I try to initialize decompresor with parameters MAX_WBITS,-MAX_WBITS,30 but it did not help.How can I solve this problem?
Code example :
//functions
InitZDecompressor = ( int (WINAPI *)( z_stream_s*, int,const char*,int)) GetProcAddress(zlibdll,"inflateInit2_");
ZDecompressor = (int (WINAPI *)(z_stream_s*,int)) GetProcAddress(zlibdll,"inflate");
ResetZDecompressor = (int (WINAPI *)(z_stream_s*)) GetProcAddress(zlibdll,"inflateEnd");
//initialize
__int32 Decoder(unsigned __int8* PDU, unsigned __int32 size, unsigned __int8 * out_b, z_stream_s & stream, bool & IsInit)
{
if (IsDllLoaded == false || PDU == nullptr) { return 0; }//if Zlib DLL was not loaded, or incoming packet is not cTCP
if ( !IsInit )
{
SecureZeroMemory(&stream, sizeof(stream));
auto res = InitZDecompressor( &stream, MAX_WBITS , "1.2.11", sizeof(z_stream_s));//initialize only one time
IsInit = true;
}
stream.next_in = PDU;
stream.avail_in = size;
stream.next_out = out_b;
stream.avail_out = 1048576;
stream.total_out = 0;
__int32 ret = 0;
//inflate
while ( stream.avail_in && ret == 0 )
{
ret = ZDecompressor(&stream, 2);
}
return ret;
}
//inflateEnd
void ResetDecompessor(bool & isInit, z_stream_s & stream)
{
if (isInit){
ResetZDecompressor(&stream);
isInit = false;
memset(&stream, 0 ,sizeof(stream));
}
}
//test func
void testZlib(unsigned __int8 *StPt, __int64 size,z_stream_s & stream,bool & isInit)
{
// StPt - start of compressed data
//size - size of compressed data
//isInit - is zStream already initialize
unsigned __int8 * OutBuf = new unsigned __int8[ 1048576 ];
auto res = zlib->Decoder( StPt,size, OutBuf, stream, isInit );
delete [] OutBuf;
}

What's happening here is that the sender is flushing the deflate compressor with an empty stored block in order to produce a decompressible packet, and then deleting the last four bytes of the empty stored block, expecting you, the receiver, to insert that.
So what you need to do is insert the bytes 00 00 ff ff between the compressed packets, and then decompress the whole thing as one zlib stream. Do not initialize inflate for the second packet -- just keep feeding compressed data to the inflator (including the inserted bytes).

Related

C++ Converting string packet to iphdr - what should be the format of string packet?

So I have this line of code:
struct iphdr *ip_header = (struct iphdr*) packet.c_str();
from ip.h:
struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ihl:4;
unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int version:4;
unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
u_int8_t tos;
u_int16_t tot_len;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t check;
u_int32_t saddr;
u_int32_t daddr;
/*The options start here. */
};
I captured a DNS packet using wireshark and I got this sample packet:
0000 e0 8e 3c 1c c0 07 ac bc 32 83 84 d9 08 00 45 00
0010 00 3f 51 45 00 00 40 11 aa b3 c0 a8 fe 65 c0 a8
0020 fe fe 0e 76 00 35 00 2b d5 1c 9c 0a 01 00 00 01
0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c
0040 65 03 63 6f 6d 02 70 68 00 00 01 00 01
I removed the eth header and so I'm left with this:
0000 45 00
0010 00 3f 51 45 00 00 40 11 aa b3 c0 a8 fe 65 c0 a8
0020 fe fe 0e 76 00 35 00 2b d5 1c 9c 0a 01 00 00 01
0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c
0040 65 03 63 6f 6d 02 70 68 00 00 01 00 01
The first part (45 00 00 3f 51 45 00 00 40 11) translates to this:
45 0100 .... = Version: 4
.... 0101 = Header Length: 20 bytes (5)
00 Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
00 3f Total Length: 63
51 45 Identification: 0x5145 (20805)
00 00 Flags: 0x00
Fragment offset: 0
40 Time to live: 64
11 Protocol: UDP (17)
My question is: what should be the format of the string variable packet? I have tried this:
std::string packet = "45 00 00 3f 51 45 00 00 40 11";
but for ip_header->protocol I get 48 '0' instead of 17.
Also I'm wondering, why is the protocol not on the 9th byte? I was assuming it should be on the 9th based on the structure of iphdr.
Would highly appreciate anyone's help. Thanks a lot!
Your basic assumption has some problems. You're using a string and you assume that if you cast it to some structure definition it will automatically (and auto-magically) convert it to the proper binary representation of that structure definition. This is not the case. Let's say you have a structure 'struct Test { unsigned int t; }' and a string 'std::string st = "12"'. And you do 'struct Test *pt = st.c_str();'. The ASCII representation of "12" would be 0x31 0x32 so now *pt points to a memory location starting with 31 32. Casting this to in integer (assume we have a big-endian system and assume the unsigned int is two bytes) results in 0x3132 (decimal 12594).

SSL_accept returns SSL_ERROR_SSL

I have a strange error working with openssl in c++ with non blocking sockets.
SSL_accept return SSL_ERROR_SSL.
error string is
"error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol"
as obtained from
ERR_error_string(ERR_get_error(), NULL);
ssldump:
New TCP connection #1: localhost(35677) <-> localhost(8084)
1 1 1443513828.4788 (0.0001) C>SV3.1(153) Handshake
ClientHello
Version 3.3
random[32]=
e9 fc d9 2b 25 20 77 9f 5f a4 b1 eb 5d 50 15 f2
38 7a a9 86 16 49 f8 a3 e9 00 7f 93 11 cd 7b b1
cipher suites
Unknown value 0xc02b
Unknown value 0xc02f
Unknown value 0xc00a
Unknown value 0xc009
Unknown value 0xc013
Unknown value 0xc014
Unknown value 0xc012
Unknown value 0xc007
Unknown value 0xc011
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
Unknown value 0x45
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Unknown value 0x88
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
Unknown value 0x41
TLS_RSA_WITH_AES_256_CBC_SHA
Unknown value 0x84
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
compression methods
NULL
1 2 1443513828.4790 (0.0002) S>CV3.3(53) Handshake
ServerHello
Version 3.3
random[32]=
aa d6 10 d1 eb b5 de b1 ed f8 6b 2f 44 fa 9f 57
14 1d c0 27 a1 e9 24 3a 20 cb 09 fa 75 33 1c c7
session_id[0]=
cipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
compressionMethod NULL
1 3 1443513828.4790 (0.0000) S>CV3.3(1003) Handshake
Certificate
certificate[993]=
30 82 03 dd 30 82 02 c5 a0 03 02 01 02 02 09 00
bc 6b da c1 c3 f0 3f 14 30 0d 06 09 2a 86 48 86
f7 0d 01 01 0b 05 00 30 81 84 31 0b 30 09 06 03
55 04 06 13 02 49 4e 31 0b 30 09 06 03 55 04 08
0c 02 49 4e 31 10 30 0e 06 03 55 04 07 0c 07 67
75 72 67 61 6f 6e 31 0e 30 0c 06 03 55 04 0a 0c
05 69 72 65 78 78 31 0c 30 0a 06 03 55 04 0b 0c
03 64 65 76 31 12 30 10 06 03 55 04 03 0c 09 6c
6f 63 61 6c 68 6f 73 74 31 24 30 22 06 09 2a 86
48 86 f7 0d 01 09 01 16 15 76 69 6b 61 73 73 6f
6f 64 31 31 40 67 6d 61 69 6c 2e 63 6f 6d 30 1e
17 0d 31 35 30 39 32 39 30 38 30 32 35 36 5a 17
0d 31 36 30 39 32 38 30 38 30 32 35 36 5a 30 81
84 31 0b 30 09 06 03 55 04 06 13 02 49 4e 31 0b
30 09 06 03 55 04 08 0c 02 49 4e 31 10 30 0e 06
03 55 04 07 0c 07 67 75 72 67 61 6f 6e 31 0e 30
0c 06 03 55 04 0a 0c 05 69 72 65 78 78 31 0c 30
0a 06 03 55 04 0b 0c 03 64 65 76 31 12 30 10 06
03 55 04 03 0c 09 6c 6f 63 61 6c 68 6f 73 74 31
24 30 22 06 09 2a 86 48 86 f7 0d 01 09 01 16 15
76 69 6b 61 73 73 6f 6f 64 31 31 40 67 6d 61 69
6c 2e 63 6f 6d 30 82 01 22 30 0d 06 09 2a 86 48
86 f7 0d 01 01 01 05 00 03 82 01 0f 00 30 82 01
0a 02 82 01 01 00 e2 9e cb 0c 9a c2 a4 0a ff 81
77 23 ad 74 c6 a0 12 9f f4 a4 86 94 bf 02 57 cc
ff 13 cf 4f 13 83 6e 70 8b 2d ee 92 93 94 44 d4
db 20 e1 67 65 3a 67 c1 d5 91 67 ab f9 98 aa 59
16 b4 38 99 92 66 c2 de e7 88 82 cd a0 10 95 89
78 f5 64 6a e5 b6 75 a2 e0 d0 76 c3 57 92 03 c7
d3 7d f3 c5 18 e5 bf 8d f5 71 17 4c dd 18 fa 11
8c d1 ed 8b 0f b6 5c fb 16 bf 5a 44 23 71 c8 83
83 5a 4d ca b0 8c 15 96 66 dc cd 9a 06 33 b3 eb
71 43 25 b1 0f df 1a c6 f1 7a 4c 4d 5e 34 12 b7
70 76 b6 f9 7e 40 6c 2e 70 df 26 cd f9 c9 0b 90
57 dd 0b c3 57 b8 55 ad 63 13 16 15 bf 8d 3b 48
9d 11 cf 15 55 a1 f2 ab ff 8f 43 48 09 e7 c9 b0
21 66 e7 e4 76 14 aa d4 a9 88 ef bf e1 db 0f b3
27 95 d0 c9 50 6f 36 c8 5e 47 3f c3 a8 59 9c a6
8a 75 57 0b db 83 c6 08 13 fa 9c 64 3c 5a 4e d5
ba 4f 23 39 67 77 02 03 01 00 01 a3 50 30 4e 30
1d 06 03 55 1d 0e 04 16 04 14 29 86 80 ff 9c 14
00 5e 2e 89 81 4a 1e 3c 32 82 ec 44 35 7b 30 1f
06 03 55 1d 23 04 18 30 16 80 14 29 86 80 ff 9c
14 00 5e 2e 89 81 4a 1e 3c 32 82 ec 44 35 7b 30
0c 06 03 55 1d 13 04 05 30 03 01 01 ff 30 0d 06
09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01
00 c9 f4 f7 0f bd a4 f2 81 e4 4e c5 4d 86 9d f3
30 fe df f6 b1 b5 a3 a6 ef 41 51 fc f3 1b c5 be
e1 1f 75 fe f1 ee 94 95 54 c7 07 13 d4 b6 89 2b
a3 86 e3 7b 12 6d 0a 51 66 31 74 d5 83 67 92 79
45 b3 03 1d 77 6b b0 71 a0 07 c0 06 e6 6b 81 74
01 8e 6d a6 c1 82 8b 34 b2 6c 52 b9 3e a6 c0 c5
ce f6 c8 b2 4b 6a 8c 43 4a 20 38 61 8a 09 1f 39
cd e6 4a 0b 6c 89 b8 88 74 d7 1e fa 86 dc 0a cd
d4 73 39 5f 53 4b 13 79 f8 cd 62 ee 38 42 61 56
26 31 44 ac 5b 39 24 2b 3f f9 21 b4 59 25 14 95
69 e6 33 41 df ef b5 ea 20 7d 38 a9 f4 c3 d1 f7
c5 37 4a c9 01 cd f4 3a e7 3c a7 16 33 0f 5d 46
19 bc 50 3d 33 05 63 ee 29 51 d1 79 c4 01 04 0f
be 27 65 57 ab e5 e8 d3 bf 4d 11 55 bc 52 e4 9f
d9 0c 87 be a9 62 9d be 65 21 a8 8a 46 63 d1 91
f9 2b e1 c6 5d 33 fb ae b6 9e a0 36 0b 37 2a fa
3b
1 4 1443513828.4790 (0.0000) S>CV3.3(4) Handshake
ServerHelloDone
1 5 1443513828.4800 (0.0009) C>SV3.3(262) Handshake
ClientKeyExchange
EncryptedPreMasterSecret[256]=
76 58 13 c2 dd ed fb 6e 7b 49 aa 0c 26 40 a1 1f
8b 87 b0 f6 a5 f8 24 fe 0c 7b a9 e6 b0 51 b1 92
2c 52 33 ba af 2a d2 52 b8 80 0f ea fd 24 b7 89
15 2f 0e 90 86 ef 9c 9d 52 02 ca 56 09 b5 81 5f
e1 05 a8 9a 44 32 7f 4f ec 58 33 4a 97 96 23 15
7d a8 1d 8c bc 5d 20 13 39 54 2f 61 27 be aa 6a
ec 49 be 82 cc 2b c7 3d a3 b0 cb 4f 26 cb 14 41
d4 4b 00 57 6f 52 2b 66 aa 23 97 ed e9 e7 9c d9
ed 81 28 0c 08 9f dd 9d e4 00 b5 ba aa a4 f6 3b
23 87 f6 da 64 c0 1e 33 87 bb ef bc c3 fe 28 64
d1 c8 ff ae f9 3f 5a fe 38 e6 ab 3e 34 2c b5 96
f7 a8 99 b6 8e b3 46 d3 c9 f8 f8 94 26 97 27 85
5f 3e ff 85 15 5f c8 1f 10 53 26 e4 88 32 4f 48
62 87 ac a8 9f 14 f1 e3 f4 c4 1a 71 49 e6 33 15
16 66 66 ec 68 ee f7 91 0c 4c b3 3a 49 88 e1 31
a5 fe 4c 31 35 3d dc 01 f6 be f2 e5 65 a0 bb 78
1 6 1443513828.4800 (0.0000) C>SV3.3(1) ChangeCipherSpec
1 7 1443513828.4800 (0.0000) C>SV3.3(64) Handshake
Unknown SSL content type 72
1 1443513828.4801 (0.0001) S>C TCP RST
I am not sure why the server resets the connection.
I am using a self signed certificate to test a websocket connection using scheme wss. Client is Mozilla Firefox and websocket server is what I am trying to implement.
Any pointers on why the server is resetting the connection?
error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol
What possible reason could throw unknown protocol?
Thanks
Edited: Adding code. It is not all the code but gives a fair idea of what i did.
Here is how my code looks like:
/*
this the main method that accepts incoming connection on a listening socket.
*/
SecureServer::Accept()
{
int ret = 0;
while(!mFinished) {
ret = epoll_wait(millis);
if(ret == -1) {
continue;
}
else if(ret == 0) {
idle(0);
}
else if(ret > 0) {
//some events are triggered
for(int i=0; i<ret; i++) {
//getEvent method is in the base class.
//SecureServer is derived from this class.
//Base class is just an epoll wrapper
epoll_event* ev = getEvent(i);
//check for error
if( (ev->events & EPOLLERR) || (ev->events & EPOLLHUP) || !(ev->events & EPOLLIN)) {
ERROR(Log::eSecureServer, "Error occured on fd = %d", ev->data.fd);
removeEpollFd(ev->data.fd);
continue;
}
//check if its a new incoming connection on server socket
else if(ev->data.fd == mServerSocket) {
//accept the connection
struct sockaddr peerAddress;
socklen_t socklen = sizeof(peerAddress);
int newSocket = accept(mSocket, &peerAddress, &socklen);
if(newSocket == -1) {
ERROR(Log::eSecureServer, "Error in accept, listen address = %s, port = %d epoll_wait returned = %d", mHost.c_str(), mPort, ret);
continue;
}
rxUShort port = ntohs(*((rxUShort*) &(peerAddress.sa_data[0])));
char ipPort[32] = {0};
sprintf(ipPort, "%hhu.%hhu.%hhu.%hhu:%hu", peerAddress.sa_data[2],peerAddress.sa_data[3],peerAddress.sa_data[4],
peerAddress.sa_data[5],port);
INFO(Log::eSecureServer, "SecureTCPServer received incoming client connection from = %s", ipPort);
//add epoll fd
// This method also makes the socket NON BLOCKING
addEpollFd(newSocket);
}
//check the handshake from a previously accepted connection
else {
//process the handshake
processHandshake(ev->data.fd);
}
}
}
}
}
/*
This method determines the client and server protocol
*/
int Protocol::processHandshake(int fd)
{
int length = 0;
length = recv(fd, handshake, 1024, MSG_PEEK);
if(length == 0) {
return UNKNOWN_PROTOCOL;
}
else if((bcmp(handshake, "\x16", 1) == 0) ||
(bcmp(handshake, "\x80", 1) == 0)) {
//secure connection requested on this fd
SSL* pSSL = 0;
int ret = NewSSLSocket(pSSL, fd);
if(SSL_ERROR_NON == ret) {
///success
}
else {
if(SSL_ERROR_WANT_READ == ret || SSL_ERROR_WANT_WRITE == ret) {
NFO(Log::eProtocol, "Handshake error, in progress.");
return eProtocolHandshakeInProgress;
} else if(SSL_ERROR_SSL == ret) {
INFO(Log::eProtocol, "Handshake error, library error");
return eProtocolInvalidHeader;
} else if(SSL_ERROR_SYSCALL == ret) {
INFO(Log::eProtocol, "Handshake error, possibly syscall error");
return eProtocolInvalidHeader;
}
SSL_free(pSSL);
}
}
}
int Protocol::NewSSLSocket(SSL* pSSL, rxUInt fd)
{
pSSL = SSL_new(mSSLContext);
SSL_set_fd(pSSL, fd);
int ret = SSL_accept(pSSL);
switch(SSL_get_error(pSSL, ret)) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
INFO(Log::eNetwork, "SSL Handshake is in progress on fd = %d %s", fd, ERR_error_string(ERR_get_error(), NULL));
return SSL_ERROR_WANT_READ;
}
break;
case SSL_ERROR_SYSCALL:
{
INFO(Log::eNetwork, "SSL syscall error during handshake on fd = %d %s", fd, ERR_error_string(ERR_get_error(), NULL));
return SSL_ERROR_SYSCALL;
}
break;
case SSL_ERROR_SSL:
{
INFO(Log::eNetwork, "SSL library error during handshake on fd = %d %s", fd, ERR_error_string(ERR_get_error(), NULL));
return SSL_ERROR_SSL;
}
case SSL_ERROR_NONE:
{
INFO(Log::eNetwork, "SSL handshake on fd = %d complete", fd);
return SSL_ERROR_NONE;
}
break;
default:
{
INFO(Log::eNetwork, "SSL unknown error during handshake on fd = %d %s", fd, ERR_error_string(ERR_get_error(), NULL));
return -1;
}
break;
}
return -1;
}
//Protocol Constructor Init the SSL Context
Protocol::Protocol()
{
const SSL_METHOD* pSSLMethod = SSLv23_server_method();
char err[1024] = {0};
mSSLContext = SSL_CTX_new(pSSLMethod);
if(mSSLContext == NULL) {
ERROR(Log::eNetwork, "Failed to initialize SLS_CTX. TLS Unavaliable.");
ERROR(Log::eNetwork, ERR_error_string(ERR_get_error(), err));
} else
INFO(Log::eNetwork, "Initialized SSL Context.");
SSL_CTX_set_cipher_list(mSSLContext, "ALL");
//Load the SSL Certificates
rxUInt ret = 0;
ret = SSL_CTX_use_certificate_file(mSSLContext, mCACertificateFile.c_str(), SSL_FILETYPE_PEM);
if(ret <=0 ) {
ERROR(Log::eNetwork, "Failed to read ssl sertificate. We should exit.");
ERROR(Log::eNetwork, ERR_error_string(ERR_get_error(), err));
} else
INFO(Log::eNetwork, "SSL Certificate read complete. OK!");
//Load the private key file
ret = SSL_CTX_use_PrivateKey_file(mSSLContext, mPrivateKeyFile.c_str(), SSL_FILETYPE_PEM);
if(ret <=0 ) {
ERROR(Log::eNetwork, "Failed to read private key file. We should exit.");
ERROR(Log::eNetwork, ERR_error_string(ERR_get_error(), err));
} else
INFO(Log::eNetwork, "Private Key read complete. OK!");
if(!SSL_CTX_check_private_key(mSSLContext)) {
ERROR(Log::eNetwork, "Private key does not match the SSL Certificate. We should exit.");
ERROR(Log::eNetwork, ERR_error_string(ERR_get_error(), err));
} else
INFO(Log::eNetwork, "Private Key and SSL Certificate Matched. OK!");
}
1 7 1443513828.4800 (0.0000) C>SV3.3(64) Handshake
Unknown SSL content type 72
My guess is that you are sending some plain data on the connection, i.e. write to the plain socket instead to the SSL socket. This is just a guess because you did not provide any code but looking for such error one finds issues like this.

RSAES_OAEP_SHA_Decryptor MaxPlaintextLength returning zero

I have to write a small authentication server that, when a client connects, sends a RSA public exponent and modulus to it, and the client returns the username and password encrypted with them. The part where I get the exponent and modulus works fine, the client receives them, and sends the encoded block back; that's not a problem. The problem is in decoding it: the RSA Decryptor always returns 0 as MaxPlaintextLength, and no matter how many different ways I try to move the data around, I can't get it to work.
I'm providing hex dumps of the different parts after the code.
// These are static in the namespace to keep the key loaded.
static CryptoPP::AutoSeededRandomPool rsaRng;
static CryptoPP::InvertibleRSAFunction rsaParameters;
static CryptoPP::RSA::PrivateKey rsaPrivateKey(rsaParameters);
// This is done when the client connects.
{
rsaPrivateKey.GenerateRandomWithKeySize(rsaRng, 1024);
// This is where GetPublicExponent() and GetModulus() are
// encoded and sent to the client. They are sent correctly
// and I receive the encrypted data in a char buffer.
}
// This runs when I receive the encrypted data, which starts
// at &dataBuffer[7] and has a length of rsaPayloadLen.
{
int rsaPlainSize;
byte *rsaBuffer;
rsaBuffer = new byte[rsaPayloadLen];
memcpy(&rsaBuffer[0], &dataBuffer[7], rsaPayloadLen);
CryptoPP::SecByteBlock rsaCypher(rsaBuffer, rsaPayloadLen);
CryptoPP::RSAES_OAEP_SHA_Decryptor rsaDecryptor(rsaPrivateKey);
// At this point I inspected rsaCypher and it does contain the
// expected binary data, and rsaCypher.size() returns 256.
rsaPlainSize = rsaDecryptor.MaxPlaintextLength(rsaCypher.size());
// rsaPlainSize is 0. I have no idea why!
}
Hex dumps of everything at the time of calling MaxPlaintextLength:
rsaPrivateKey.GetPublicExponent():
000000: 11 .
rsaPrivateKey.GetPrivateExponent():
000000: 10 7a fd fd 9e a9 72 8c c3 5d 5b 80 e8 f4 6f bc .z....r..][...o.
000010: bc 6a 7a 51 4f 9f af d3 e4 76 a5 4a 9d fe 17 37 .jzQO....v.J...7
000020: 03 cf 82 24 33 e2 a0 d8 97 26 0a 6b ac 9d b1 de ...$3....&.k....
000030: 39 d5 3a 93 aa 65 66 be 17 43 3c 00 20 77 68 0a 9.:..ef..C<. wh.
000040: ac 2f 77 1e b8 c4 7f 64 52 54 7c 17 54 b6 e6 a4 ./w....dRT|.T...
000050: 95 49 60 7b 7b 16 6a 41 72 54 03 a2 2d 3a 80 8b .I`{{.jArT..-:..
000060: aa 74 fa 77 22 5d 0a d9 81 b2 b2 48 01 db 43 e8 .t.w"].....H..C.
000070: 16 1c c4 c3 a6 bf 45 7e 90 d3 6a 37 10 40 9f 71 ......E~..j7.#.q
rsaPrivateKey.GetModulus():
000000: d2 20 26 61 a6 f0 74 82 ba e6 4e ab 9a 2c 90 a6 . &a..t...N..,..
000010: 62 4d 97 8c b7 34 01 cd a0 e8 bb 77 5e 67 a7 fd bM...4.....w^g..
000020: 70 95 bb 4d 95 89 82 c9 87 25 04 dc d8 da 9b d1 p..M.....%......
000030: 61 5e aa da bc 8c dd f7 a8 99 3d 01 9d f2 6e 89 a^........=...n.
000040: e4 75 ec 91 31 e9 86 f4 da 43 4a ca a4 66 6b 04 .u..1....CJ..fk.
000050: c2 c9 a1 18 1d fa 81 b0 6e ef a5 13 04 44 88 89 ........n....D..
000060: 42 41 be 9c 7c 77 75 96 50 07 70 ad eb 60 e5 05 BA..|wu.P.p..`..
000070: aa a8 d8 27 03 28 cf bb c7 f5 cb 0d b3 b3 96 7f ...'.(..........
rsaPrivateKey.GetPrime1():
000000: d7 9e af ac e4 04 42 e4 58 9c 39 19 0e 56 7c ef ......B.X.9..V|.
000010: b3 bf b6 26 73 25 d8 ab d7 5e d1 e0 56 49 ae 66 ...&s%...^..VI.f
000020: c4 d8 81 bc d0 be c2 ef f4 6a 09 72 ef 72 35 7e .........j.r.r5~
000030: 15 f4 f9 3b f8 be f9 3a a1 0d 3e d0 eb c8 34 11 ...;...:..>...4.
rsaPrivateKey.GetPrime2():
000000: f9 7a 0e 1c 9a 1b eb d1 67 f1 e3 88 1d f3 f1 62 .z......g......b
000010: 9f a2 5c cb 49 76 de 42 25 e1 a4 de ed 50 f3 2d ..\.Iv.B%....P.-
000020: c0 15 c3 70 b5 96 68 51 25 f7 06 24 e4 43 0d b8 ...p..hQ%..$.C..
000030: 7a c5 12 2c 7c 63 20 73 70 61 01 fe b8 b3 71 8f z..,|c spa....q.
Plain text buffer that was encrypted:
000000: 73 74 72 69 6e 67 62 75 66 66 65 72 00 00 00 00 stringbuffer....
000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
rsaCypher:
000000: 0e 9e bd 34 10 16 98 a5 b8 e4 0c 9b 4f 23 71 6d ...4........O#qm
000010: af d6 e8 c1 4d 97 b9 32 cb 25 eb 01 fe 4f 5c 79 ....M..2.%...O\y
000020: 2d d8 32 c4 4f fa e9 2e 58 dd fd 37 7f 08 97 d8 -.2.O...X..7....
000030: 95 bb 6f 04 46 fa 83 77 05 01 43 75 ca be b4 4a ..o.F..w..Cu...J
000040: 60 f9 e7 4a 91 3d bc ac fb e9 41 f3 9d b7 df d3 `..J.=....A.....
000050: a7 03 80 3a 7f 35 98 46 ca 06 b1 f3 d1 7b 56 83 ...:.5.F.....{V.
000060: 1b 00 7d 97 59 39 be 46 d5 cf 6d 2c b3 a7 8e 30 ..}.Y9.F..m,...0
000070: 39 ca ca d5 59 a2 71 43 e7 7e 75 b3 3c d6 a3 a5 9...Y.qC.~u.<...
000080: aa 89 e3 e9 32 e1 a9 c1 a5 a8 f5 66 be 7f c9 ba ....2......f....
000090: 65 35 0f 61 a0 d4 fa c7 ac 8e 28 7c 39 26 3f 01 e5.a......(|9&?.
0000a0: 34 ad 82 69 5e c4 ab 92 48 47 42 04 02 48 79 c4 4..i^...HGB..Hy.
0000b0: 39 6e f2 2c 7c 19 71 34 36 38 1c eb c1 f2 33 f0 9n.,|.q468....3.
0000c0: 49 b9 7e bb c3 16 ed d7 f7 3e 10 a7 cc 2b 8c 31 I.~......>...+.1
0000d0: f1 17 c7 a5 49 ce dd a3 c6 e2 9c 3c 2f 37 e4 97 ....I......</7..
0000e0: ac b7 24 17 b3 f8 75 6f 2a 85 cb 23 7a e1 77 72 ..$...uo*..#z.wr
0000f0: 02 0b 90 28 9b 9b ff 5d 6f 9b 11 11 d3 8b dd 4b ...(...]o......K
rsaCypher.size(): 256
rsaDecryptor.MaxPlaintextLength(rsaCypher.size()): 0
I'm really completely at a loss and the only reason I've spent the whole weekend fighting this is because I'm going to need CryptoPP later for Blowfish and Adler32, otherwise I would have just used another RSA library.
RSAES_OAEP_SHA_Decryptor MaxPlaintextLength returning zero...
Your calculation of rsaPayloadLen is probably not correct. I would suggest you check the size of the ciphertext before you transmit it and after you recover it. I think its size is rsaPayloadLen in you code above.
From the comments in cryptlib.h:
//! maximum length of plaintext for a given ciphertext length
/*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */
virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0;
I cannot duplicate when I take plain text, encrypt it, and then pass ciphertext.size() into MaxPlaintextLength. I can duplicate if I pass ciphertext.size() - 1 into MaxPlaintextLength.
As a work around to get you a little further along, you might try using FixedMaxPlaintextLength(). It takes no arguments and only depends upon the public key length. You can use it to find the largest buffer based on the key. But you could fail on decryption.
You should probably show us your encryption code, too. You might not be sizing a buffer correctly.
The whole problem was the key size. The doc said I should use a 1024-bit key, but the other program was expecting a 1152-byte key; apparently that change was never documented. Everything works fine after changing a single line:
rsaPrivateKey.GenerateRandomWithKeySize(rsaRng, 1152);
Leaving this answer here in case someone else ever has this problem. Check the key sizes, and don't trust the documentation!

FFMPEG: directly decode packets after encoding

using FFMPEG API, I try to encode a x264 video to a MP4 file with 0 frame latency and also, in realtime, show the currently encoded frame on screen (with encoding artifacts). The encoding to the file works, but so far I don't get the frames decoded right after writing them to the file. What I try is to feed the packetdata that is returned from avcodec_encode_video() right into avcodec_decode_video2() but the function returns -1 and the cmd output shows:
[h264 # 00000000025F0710] non-existing PPS 0 referenced
[h264 # 00000000025F0710] decode_slice_header error
[h264 # 00000000025F0710] no frame
here is some code i use for encoding:
AVPacket FFMpegEncoder2::write_video_frame(AVFrame* pic, int &numBytes)
{
int out_size, ret;
AVPacket pkt;
/* encode the image */
out_size = avcodec_encode_video(m_cctx, m_outbuf,
m_outbufSize, pic);
/* If size is zero, it means the image was buffered. */
assert(out_size>0) //0 frame delay
av_init_packet(&pkt);
if (m_cctx->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(m_cctx->coded_frame->pts,m_cctx->time_base, m_video_st->time_base);
if (m_cctx->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = m_video_st->index;
pkt.data = m_outbuf;
pkt.size = out_size;
/* Write the compressed frame to the media file. */
ret = av_interleaved_write_frame(m_fctx, &pkt);
if (ret != 0) {
fprintf(stderr, "Error while writing video frame\n");
exit(1);
}
numBytes = out_size;
return pkt;
}
and then I take this returned packet and feed it into the decoder:
const AVFrame* FFMpegDecoder2::decode(AVPacket* packet){
AVPacket pkt;
av_init_packet(&pkt);
pkt.size = packet->size;
pkt.data = packet->data;
int len=0;
int got_picture=0;
while (pkt.size > 0) {
len = avcodec_decode_video2(m_cctx, m_frame, &got_picture, &pkt);
if (len < 0) {
fprintf(stderr, "Error while decoding frame %d\n", m_f);
exit(1);
}
if (got_picture) {
assert(pkt.size==len);
m_f++;
}
pkt.size -= len;
pkt.data += len;
}
assert(got_picture);
return m_frame;
}
but as stated, avcodec_decode_video2() returns -1
what am I doing wrong? Do i need to feed some headerdata into the decoder first somehow?
//edit:
if i set
m_formatCtx->oformat->flags &= ~AVFMT_GLOBALHEADER;
m_codecctx->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
then i can decode the returned packet without error, but the written mp4 file will be black.
//edit: this is how i setup the decoder:
FFMpegDecoder2::FFMpegDecoder2(CodecID id)
: m_codec(NULL)
, m_cctx(NULL)
{
/* Initialize libavcodec, and register all codecs and formats. */
avcodec_register_all();
m_codec = avcodec_find_decoder(id);
if (!m_codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
m_cctx = avcodec_alloc_context3(m_codec);
m_cctx->codec = m_codec;
m_cctx->pix_fmt = PIX_FMT_YUV420P;
avcodec_open2(m_cctx, m_codec, NULL);
//alloc frame
m_frame = avcodec_alloc_frame();
}
this is what the memory window shows for the first packet (didn't copy all. the size of the first packet is 7859):
0x0000000002E66670 00 00 01 06 05 ff ff 55 dc 45 e9 bd e6 d9 48 b7 96 2c d8 20 d9 23 ee ef 78 32 36 34 20 2d 20 63 6f 72 65 20 31 32 30 20 72 32 31 34 36 20 62 .....ÿÿUÜEé.æÙH·–,Ø Ù#îïx264 - core 120 r2146 b
0x0000000002E6669F 63 64 34 31 64 62 20 2d 20 48 2e 32 36 34 2f 4d 50 45 47 2d 34 20 41 56 43 20 63 6f 64 65 63 20 2d 20 43 6f 70 79 6c 65 66 74 20 32 30 30 33 cd41db - H.264/MPEG-4 AVC codec - Copyleft 2003
0x0000000002E666CE 2d 32 30 31 31 20 2d 20 68 74 74 70 3a 2f 2f 77 77 77 2e 76 69 64 65 6f 6c 61 6e 2e 6f 72 67 2f 78 32 36 34 2e 68 74 6d 6c 20 2d 20 6f 70 74 -2011 - http://www.videolan.org/x264.html - opt
0x0000000002E666FD 69 6f 6e 73 3a 20 63 61 62 61 63 3d 30 20 72 65 66 3d 33 20 64 65 62 6c 6f 63 6b 3d 31 3a 30 3a 30 20 61 6e 61 6c 79 73 65 3d 30 78 33 3a 30 ions: cabac=0 ref=3 deblock=1:0:0 analyse=0x3:0
0x0000000002E6672C 78 31 31 33 20 6d 65 3d 68 65 78 20 73 75 62 6d 65 3d 34 20 70 73 79 3d 31 20 70 73 79 5f 72 64 3d 31 2e 30 30 3a 30 2e 30 30 20 6d 69 78 65 x113 me=hex subme=4 psy=1 psy_rd=1.00:0.00 mixe
0x0000000002E6675B 64 5f 72 65 66 3d 31 20 6d 65 5f 72 61 6e 67 65 3d 31 36 20 63 68 72 6f 6d 61 5f 6d 65 3d 31 20 74 72 65 6c 6c 69 73 3d 30 20 38 78 38 64 63 d_ref=1 me_range=16 chroma_me=1 trellis=0 8x8dc
0x0000000002E6678A 74 3d 31 20 63 71 6d 3d 30 20 64 65 61 64 7a 6f 6e 65 3d 32 31 2c 31 31 20 66 61 73 74 5f 70 73 6b 69 70 3d 31 20 63 68 72 6f 6d 61 5f 71 70 t=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp
0x0000000002E667B9 5f 6f 66 66 73 65 74 3d 30 20 74 68 72 65 61 64 73 3d 31 20 73 6c 69 63 65 64 5f 74 68 72 65 61 64 73 3d 30 20 6e 72 3d 30 20 64 65 63 69 6d _offset=0 threads=1 sliced_threads=0 nr=0 decim
0x0000000002E667E8 61 74 65 3d 31 20 69 6e 74 65 72 6c 61 63 65 64 3d 30 20 62 6c 75 72 61 79 5f 63 6f 6d 70 61 74 3d 30 20 63 6f 6e 73 74 72 61 69 6e 65 64 5f ate=1 interlaced=0 bluray_compat=0 constrained_
0x0000000002E66817 69 6e 74 72 61 3d 30 20 62 66 72 61 6d 65 73 3d 30 20 77 65 69 67 68 74 70 3d 32 20 6b 65 79 69 6e 74 3d 32 35 20 6b 65 79 69 6e 74 5f 6d 69 intra=0 bframes=0 weightp=2 keyint=25 keyint_mi
0x0000000002E66846 6e 3d 32 20 73 63 65 6e 65 63 75 74 3d 34 30 20 69 6e 74 72 61 5f 72 65 66 72 65 73 68 3d 30 20 72 63 3d 61 62 72 20 6d 62 74 72 65 65 3d 30 n=2 scenecut=40 intra_refresh=0 rc=abr mbtree=0
0x0000000002E66875 20 62 69 74 72 61 74 65 3d 34 30 30 20 72 61 74 65 74 6f 6c 3d 31 2e 30 20 71 63 6f 6d 70 3d 30 2e 36 30 20 71 70 6d 69 6e 3d 30 20 71 70 6d bitrate=400 ratetol=1.0 qcomp=0.60 qpmin=0 qpm
0x0000000002E668A4 61 78 3d 36 39 20 71 70 73 74 65 70 3d 34 20 69 70 5f 72 61 74 69 6f 3d 31 2e 34 30 20 61 71 3d 31 3a 31 2e 30 30 00 80 00 00 00 01 65 88 84 ax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00.€....eˆ.
0x0000000002E668D3 11 ef ff f8 22 0f 8a 00 02 09 7e 38 00 08 45 c7 00 01 1d c9 39 3d 87 ff e0 ac 13 03 6d 05 f1 00 10 00 10 12 88 04 00 04 02 60 70 4e 2d cc 38 .ïÿø".Š...~8..EÇ...É9=.ÿà¬..m.ñ.....ˆ....`pN-Ì8
0x0000000002E66902 27 16 e6 07 21 1a e6 1c 84 6b 9f f0 f0 27 15 f2 7b 87 ff c1 58 2a 8a 00 04 b8 80 00 58 00 04 02 62 01 03 c1 c1 04 63 07 04 11 88 90 b1 89 0b '.æ.!.æ..kŸðð'.ò{.ÿÁX*Š..¸€.X...b..ÁÁ.c...ˆ.±..
0x0000000002E66931 1f 2c 11 02 b1 40 00 87 8f a4 f7 0f ff 82 b0 55 06 93 41 c4 10 51 00 00 40 14 00 04 00 a3 b7 35 b7 30 38 26 1e e6 1c 13 0f 73 f2 c1 10 2b 14 .,..±#...¤÷.ÿ.°U.“AÄ.Q..#....£·5·08&.æ...sòÁ.+.
0x0000000002E66960 1f 1f 1c 32 7f 94 11 82 a1 40 01 f1 00 00 40 14 01 22 00 01 e0 1e 22 0a e3 83 1c 19 3d f8 7f e0 b0 16 03 01 22 0f 88 00 02 00 00 16 20 01 17 ...2.”..¡#.ñ..#.."..à.".ãƒ..=ø.à°...".ˆ..... ..
0x0000000002E6698F 03 84 c2 5c 87 09 84 b9 06 4a e4 a4 ae 08 82 d8 e0 00 20 0f 1d 93 df c3 fe 0b 01 54 50 07 88 a8 80 00 64 09 88 58 88 58 83 84 1d 88 38 41 d8 ..Â\.....J䤮..Øà. ..“ßÃþ..TP.ˆ¨€.d.ˆXˆXƒ..ˆ8AØ
0x0000000002E669BE f2 c1 10 2b 14 00 08 f8 e0 00 62 38 64 ff 08 70 13 0a c1 d2 e9 b5 5d ba 10 80 09 a2 01 2e 07 04 c2 dc 87 04 c2 dc 81 c8 66 b9 0e 43 35 cb 0f òÁ.+...øà.b8dÿ.p..ÁÒéµ]º.€.¢....ÂÜ..ÂÜ.Èf..C5Ë.
0x0000000002E669ED ff c1 10 27 2c 00 7e 8e 00 05 64 e4 f6 1f ff 82 28 a0 00 21 99 e3 80 00 99 ac 70 00 11 39 93 93 d8 7f fe 0a c1 40 34 9a 0b e3 40 00 84 40 01 ÿÁ.',.~Ž..däö.ÿ.( .!™ã€.™¬p..9““Ø.þ.Á#4š.ã#..#.
0x0000000002E66A1C 00 01 02 88 fd cd 7d cc 0e 08 a4 dc c3 82 29 37 3f e0 88 14 8b f1 c3 1c 03 27 f0 c3 60 a0 50 62 86 da 36 1f 10 00 0a 80 00 80 14 40 00 20 00 ...ˆýÍ}Ì..¤ÜÃ.)7?àˆ..ñÃ..'ðÃ` Pb.Ú6....€.€.#. .
and this is the encoders output (until after encoding frame 0):
[libx264 # 00000000005ADAA0] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShu
ffle SSE4.2
[libx264 # 00000000005ADAA0] profile High, level 3.0
[libx264 # 00000000005ADAA0] 264 - core 120 r2146 bcd41db - H.264/MPEG-4 AVC cod
ec - Copyleft 2003-2011 - http://www.videolan.org/x264.html - options: cabac=0 r
ef=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=4 psy=1 psy_rd=1.00:0.00 mixed
_ref=1 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pski
p=1 chroma_qp_offset=0 threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 b
luray_compat=0 constrained_intra=0 bframes=0 weightp=2 keyint=25 keyint_min=2 sc
enecut=40 intra_refresh=0 rc=abr mbtree=0 bitrate=100 ratetol=1.0 qcomp=0.60 qpm
in=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out2.mp4':
Stream #0:0: Video: h264, yuv420p, 640x480, q=-1--1, 100 kb/s, 90k tbn, 25 t
bc
[mp4 # 0000000000467570] Encoder did not produce proper pts, making some up.
This my packet data:
00 00 00 01 67 64 00 1F AC 56 24 02 80 DA 10 00
00 03 00 10 00 00 03 03 C0 F1 83 18 98 00 00 00
01 68 E8 8E 0B CB 22 C0 00 00 00 01 65 88 82 00
The first a few bytes for a first h264 packet should somewhat look like this.
00 00 00 01 ?7 ... 00 00 00 01 ?8 ... 00 00 00 01 ?5
?7 -> sps
?8 -> pps
?5 -> idr picture
There might be something else like ?6, which is sei, etc. But with SPS, PPS and the idr picture, the decoder should be able to initialize itself properly.
Another case might be the packet contains more than one picture (00 00 00 01 ?5, or 00 00 00 01 ?1). As far as I know, the decoder cannot handle h264 packets with more than one pictures properly.

Writing BMP data getting garbage

I'm working on understanding and drawing my own DLL for PDF417 (2d barcodes). Anyhow, the actual drawing of the file is perfect, and in correct boundaries of 32 bits (as monochrome result). At the time of writing the data, the following is a memory dump as copied from C++ Visual Studio memory dump of the pointer to the bmp buffer. Each row is properly allocated to 36 wide before the next row.
Sorry about the wordwrap in the post, but my output was intended to be the same 36 bytes wide as the memory dump so you could better see the distortion.
The current drawing is 273 pixels wide by 12 pixels high, monochrome...
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00
Here is the code to WRITE the file out -- verbatim immediately at the time of the memory dump from above
FILE *stream;
if( fopen_s( &stream, cSaveToFile, "w+" ) == 0 )
{
fwrite( &bmfh, 1, (UINT)sizeof(BITMAPFILEHEADER), stream );
fwrite( &bmi, 1, (UINT)sizeof(BITMAPINFO), stream );
fwrite( &RGBWhite, 1, (UINT)sizeof(RGBQUAD), stream );
fwrite( ppvBits, 1, (UINT)bmi.bmiHeader.biSizeImage, stream );
fclose( stream );
}
Here's what ACTUALLY Gets written to the file.
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00
00 00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb
00 00 00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02
eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0d 0a
8e 02 eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c
0d 0a 8e 02 eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79
bc 5c 0d 0a 8e 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00
Notice the start of the distortion with the "0d" in the result from reading the file back in the 4th line, about the 15th byte over... Then, there are a few more staggered around which in total, skew the image off by 9 bytes worth...
Obviously, the drawing portion is working ok as everything remains properly aligned in memory for the 12 lines.
Shouldn't you open the file in a compound mode i.e. writable & binary as in wb+?
Notice the start of the distortion with the "0d"
That's ASCII code for Carriage Return (CR) -- added on some OSes with newline (where a newline is actually a sequence of CR/LF). This should go away once you start writing the output in binary mode.
Your code looks neat otherwise. Cheers!
Your 0x0A (\n) gets converted to DOS format 0x0D0A (\r\n), becouse you're write the file in text mode. Switch to binary mode.
I actually just did a similar thing in java (printing bmp data to a thermal receipt printer). There are a couple of things i want to share with you:
bmp image data != an image format from microsoft. the MS bitmap has about 54 bytes of header information before any image data. (i spent a day or two working on this before I realized the difference)
bmp image data reads left to right, top to bottom, with the most significant bit on the left.
make sure the barcode image has a bitdepth of 1. this means 1 bit = 1 pixel. hexidecimal "ab" is 10101011 in binary, those 8 pixels will be filled in accordingly.
if you have a barcode 36 bytes wide, the barcode resolution is 288 x 12, not 273 x 12. (36 * 8 = 288).
the image data should be 432 bytes in size (12 rows of 36 bytes).
i dont know what this means:
Anyhow, the actual drawing of the file is perfect, and in correct boundaries of 32 bits (as monochrome result).
monochrome means its either 1 color or another. the pixel (think bit) is either filled in or it isnt.
Hope this helps