C++ display array of bytes in hex - c++

I've made a dll hook that will send address for Byte array that I need every time the event occurs on the main apps.
Display code :
void receivedPacket(char *packet){
short header = packet[2];
TCHAR str[255];
_stprintf(str, _T("Header : %lX\n"), header); // This works fine. It return 0x38 as it should.
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str, strlen(str), 0, 0);
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), packet, 34, 0, 0);
}
this is the example of the byte array from that address, and this is how I want it to be displayed :
05 01 38 00 60 00 9D 01 00 00 00 00 00 70 C9 7D 0E 00 00 00 00 00 00 00 FF 20 79 40 00 00 00 00
But, with my current code, it will only display weird symbols. So how can we convert all those weird symbol to hex?
I'm actually new to the C++.

Format each byte in the string:
static TCHAR const alphabet[] = _T("0123456789ABCDEF");
for (TCHAR * p = str; *p; ++p)
{
TCHAR const s[2] = { alphabet[p / 16], alphabet[p % 16] };
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), s, 2, 0, 0);
}

Related

C++ memcpy not copying as expected

BYTE* uMemory;
std::string data = "00 00 00 2D 01 00 B0 F9 1E 00"
data.erase(remove_if(data.begin(), data.end(), isspace), data.end());
int address = 0;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
int num2 = std::stoi(data_1, 0, 16);
memcpy(&uMemory + address, &num2, 2);
address++;
}
I'm trying to copy this into memory (2E 01 00 00 00 2D 01 00 B0 F9 1E 00) for uMemory but I don't understand the logic of it.
No matter the amount of bytes I want it to copy it always ends up like this in memory:
00 00 00 00 00 00 00 00 00 01 00 00 2D 00 00 00 01 00 00 00 00 00 00 00 B0 00 00 00 F9 00 00 00 1E 00 00 00
Your immediate problem here is that uMemory is a pointer, and in the line
memcpy(&uMemory + address, &num2, 2);
you are forming a pointer to a pointer. &uMemory has type BYTE**, so when you do pointer arithmetic you're moving over one pointer-width each time, which is apparently 4 bytes on your platform judging by your output.
You're also clobbering a random section of memory of when you write here, likely the memory holding the data object itself (since that's what's declared immediately after the pointer.)
This was my solution. I would love some alternatives for better coding practices if possible.
std::atomic<BYTE> uMemory[256];
int address = 0;
std::vector<BYTE> array;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
DWORD num2 = std::stoi(data_1, 0, 16);
array.push_back(num2);
}
std::copy(std::begin(array), std::end(array), std::begin(uMemory));
The only thing I'm not understanding is that I have to have std::atomic in order for the memory to not become random. Is there a different way of doing this?

Sending user defined struct through Apache Qpid

I try to send a user defined struct which contains substructs over AMQP from one node to another. I am using the Apache Qpid library at the moment.
(I'm currently still testing my code on the PC before i rebuild it for my other devices)
my current method consist of a conversion from the struct to a bytestring and sending that over AMQP to deconverse it on the other side.
I do the following
//user defined struct
enum Quality
{
/// <summary>Value is reliable.</summary>
QUALITY_GOOD,
/// <summary>Value not reliable.</summary>
/// <remarks>
/// A variable may be declared unreliable if a sensor is not calibrated or
/// if the last query failed but older samples are still usable.
/// </remarks>
QUALITY_UNCERTAIN,
/// <summary>Value is invalid.</summary>
/// <remarks>
/// A variable may be declared bad if the measured value is out of range or
/// if a timeout occured.
/// </remarks>
QUALITY_BAD
};
struct Payload
{
/// <summary>Identifier that uniquely points to a single instance.</summary>
DdsInterface::Id id = DdsInterface::Id();
/// <summary>Human readable short name.</summary>
std::string name = "default";
/// <summary>Actual value.</summary>
long long value;
/// <summary>Quality of the Value.</summary>
Quality quality = QUALITY_GOOD;
/// <summary>Detailed quality of the variable.</summary>
QualityDetail qualityDetail = 0;
/// <summary>Unit of measure.</summary>
PhysicalQuantity quantity = 0;
Payload();
Payload(const DdsInterface::Id id, const std::string topic, const uint64_t counter);
};
//sender function
void QpidAMQP::AMQPPublish(const Payload& payload, bool durability, bool sync)
{
// Publish to MQTT broker
qpid::messaging::Message message;
message.setDurable(durability);
char b[sizeof (payload)];
memcpy(b, &payload, sizeof(payload));
//create stream of bytes to send over the line
message.setContent(b);
//message.setContent("testIfSend");
std::string temp = message.getContent();
print_bytes(temp.c_str(), sizeof (temp));// used to check the byte data
this->sender.send(message);
this->session.sync(sync);
}
//receiver functions
void *check_for_incoming_messages(QpidAMQP* amqp_instance) //called via pthread
{
qpid::messaging::Message message;
std::cout << "check for incoming messages" << std::endl;
while(amqp_instance->getReceiver()->fetch(message, qpid::messaging::Duration::FOREVER))
{
amqp_instance->on_message(&message);
}
return nullptr;
}
void QpidAMQP::on_message(qpid::messaging::Message *message)
{
/// make sure message topic and payload are copied!!!
if (this->handler)
{
std::string temp = message->getContent();
print_bytes(temp.c_str(), sizeof (temp)); // used to check the byte data
Payload payload; //Re-make the struct
memcpy(&payload, message->getContent().c_str(), message->getContentSize());
handler->ReceivedIntegerValue(payload.id.variableId, payload.value);
}
}
I did check the byte data and they where vastly different.
sender:
[ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 60 32 bf 74 ff 7f 00 00 05 00 00 00 00 00 00 00 74 6f 70 69 63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]
receiver:
>[ 74 65 73 74 49 66 53 65 6e 64 00 00 00 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 ed ff 43 57 7f 00 00 07 00 00 00 00 00 00 00 64 65 66 61 75 6c 74 00 6d 05 77 4b 57 7f 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ]
I used the following code to print this out
void print_bytes(const void *object, size_t size)
{
// This is for C++; in C just drop the static_cast<>() and assign.
const unsigned char * const bytes = static_cast<const unsigned char *>(object);
size_t i;
printf("[ ");
for(i = 0; i < size; i++)
{
printf("%02x ", bytes[i]);
}
printf("]\n");
}
When i send only a string instead of the payload it receives on the other end. But for some reason a user defined struct doesn't work.
i want to avoid remapping everything against the qpid map because i will lose the depth of my Payload.id.
If someone has any sugestions to overcome this i would appreciatie it.
Thanks in advance,
Nick
I solved the issue.
the problem was that instead of the string instance it copied a pointer instance. By making the std::string name = "default"; into char name[20] = "default"; it copies the real character string.
This is how the publisher and subscriber encode en decode the message now.
void QpidAMQP::AMQPPublish(const Payload& payload, bool durability, bool sync)
{
// Publish to MQTT broker
//create stream of bytes to send over the line
qpid::messaging::Message message;
message.setDurable(durability);
std::string b;
b.resize(sizeof(Payload));
std::memcpy(const_cast<char*>(b.c_str()), &payload, b.size());
message.setContent(b);
std::string temp = message.getContent();
print_bytes(temp.c_str(), temp.size());
this->sender.send(message);
this->session.sync(sync);
}
void QpidAMQP::on_message(qpid::messaging::Message *message)
{
/// make sure message topic and payload are copied!!!
if (this->handler != nullptr)
{
const std::string temp = message->getContent();
print_bytes(temp.c_str(), temp.size());
Payload payload;
std::memcpy(&payload, temp.c_str(), temp.size());//sizeof(message->getContentBytes().c_str()));
handler->ReceivedIntegerValue(payload.id.variableId, payload.value);
}
}

Sudden Memory Leaks Issue

Environment:
Windows 10 Home 10.0.16299
MS Visual Studio Community 2017 Version 15.6.6
Compile Settings: 64 bit - Multi-Byte Char Set
Since a few days, I'm facing a very annoying issue of memory leaks. I tried a lot but the problems still remains.
Suddently, I got the following messages on application exit :
{7196} normal block at 0x000001FD42D0EA90, 66 bytes long.
Data: <` f ) ) > 60 C6 CC 66 F7 7F 00 00 29 00 00 00 29 00 00 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\oleinit.cpp(84) : {749} client block at 0x000001FD40F735F0, subtype c0, 104 bytes long.
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dumpcont.cpp(23) : atlTraceGeneral - a CCmdTarget object at $000001FD40F735F0, 104 bytes long
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {747} normal block at 0x000001FD40F78750, 248 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occmgr.cpp(794) : {746} normal block at 0x000001FD40F5F1D0, 8 bytes long.
Data: < f > F0 BB A3 66 F7 7F 00 00
and also I got the following messages on application exit (I got 12 in fact)
{348} normal block at 0x00000236C88FE4A0, 69 bytes long.
Data: <` > , , > 60 C6 3E BE F6 7F 00 00 2C 00 00 00 2C 00 00 00
So, when I add the following line.....
_CrtSetBreakAlloc(348);
The compiler breaks with the message The xxxx.exe has triggered a breakpoint.
Always a the same place: the line
'pData = (CStringData*)malloc( nTotalSize );' in CAfxStringMgr::Allocate
CStringData* CAfxStringMgr::Allocate( int nChars, int nCharSize ) throw()
{
size_t nTotalSize;
CStringData* pData;
size_t nDataBytes;
ASSERT(nCharSize > 0);
if(nChars < 0)
{
ASSERT(FALSE);
return NULL;
}
nDataBytes = (nChars+1)*nCharSize;
nTotalSize = sizeof( CStringData )+nDataBytes;
pData = (CStringData*)malloc( nTotalSize );
if (pData == NULL)
return NULL;
pData->pStringMgr = this;
pData->nRefs = 1;
pData->nAllocLength = nChars;
pData->nDataLength = 0;
return pData;
}
The problem arised with function that passed CString as reference parameter. Like this one:
int CFoo::GetData(CString strMainData, CString& strData, int nPos, int nLen)
{
strData = strMainData.Mid(nPos + 2, nLen);
return ( nPos + 2 + nLen);
}
Any clue why I got this ? I'm working on that app since several weeks. I never experienced this issue. I modified the function to use char* as parameter and the, a copy to the CSring in the calling function but the problem remains. This behaviour appeared two weeks ago (but I didn't notice it directly). Could it be a compiler settings ?

Using minizip to decompress a char array

I have a vector (which is just a wrapper over a char array) that is the input. The pkzip was created using c# sharpZipLib.
I stored the data into a file which I ran through a hex editor zip template that checked out. The input is good, it's not malformed. This all but the compressed data:
50 4B 03 04 14 00 00 00 08 00 51 B2 8B 4A B3 B6
6C B0 F6 18 00 00 40 07 01 00 07 00 00 00 2D 33
31 2F 31 32 38
<compressed data (6390 bytes)>
50 4B 01 02 14 00 14 00 00 00 08 00 51 B2 8B 4A
B3 B6 6C B0 F6 18 00 00 40 07 01 00 07 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D 33
31 2F 31 32 38 50 4B 05 06 00 00 00 00 01 00 01
00 35 00 00 00 1B 19 00 00 00 00
I have another vector which is to be the output. The inflated data will have about 67-68k, so I know it fits into the buffer.
For the life of me, I cannot get the minizip to inflate the former and store it into latter.
This is what I have so far:
#include "minizip\zlib.h"
#define ZLIB_WINAPI
std::vector<unsigned char> data;
/*...*/
std::vector<unsigned char> outBuffer(1024 * 1024);
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.data_type = Z_BINARY;
stream.avail_in = data.size();
stream.avail_out = outBuffer.size();
stream.next_in = &data[0];
stream.next_out = &outBuffer[0];
int ret = inflateInit(&stream);
ret = inflate(&stream, 1);
ret = inflateEnd(&stream);
I used the debugger to step through the method and monitor the ret. inflate returned value -3 with message "incorrect header check".
This is a pkzip, which is a wrapper around zlib, but minizip should be a wrapper library around zlib that should support pkzip, shouldn't it be?
How do I have to modify this to work?
Since it starts with 50 4B 03 04 it is a PKZIP file, according to https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
If these are zip files, then inflate is the wrong function. The zlib, gzip and zip formats are all different. You can read zip with zlib, if you use the right functions to do so. If you don't have the contrib, maybe download and rebuild zlib.
Here's some old code I have which works for zip files, using the zlib library. I might have moved some headers around, because the official zlib has them under zlib/contrib/minizip.
The arguments are filenames, so you'll have to modify it, or write your array to a file.
// #include <zlib/unzip.h>
#include <zlib/contrib/minizip/unzip.h>
/// return list of filenames in zip archive
std::list<std::string> GetZipFilenames(const char *szZipArchive){
std::list<std::string> results;
unzFile zip = unzOpen(szZipArchive);
if (zip){
unz_global_info info;
int rv = unzGetGlobalInfo(zip, &info);
if (UNZ_OK == unzGoToFirstFile(zip)){
do {
char szFilename[BUFSIZ];
if (UNZ_OK == unzGetCurrentFileInfo(zip, NULL, szFilename, sizeof(szFilename), NULL, 0, NULL, 0))
results.push_back(std::string(szFilename));
} while (UNZ_OK == unzGoToNextFile(zip));
}
}
return results;
}
/// extract the contents of szFilename inside szZipArchive
bool ExtractZipFileContents(const char *szZipArchive, const char *szFilename, std::string &contents){
bool result = false;
unzFile zip = unzOpen(szZipArchive);
if (zip){
if (UNZ_OK == unzLocateFile(zip, szFilename, 0)){
if (UNZ_OK == unzOpenCurrentFile(zip)){
char buffer[BUFSIZ];
size_t bytes;
while (0 < (bytes = unzReadCurrentFile(zip, buffer, sizeof(buffer)))){
contents += std::string(buffer, bytes);
}
unzCloseCurrentFile(zip);
result = (bytes == 0);
}
}
unzClose(zip);
}
return result;
}
If I understand the question correctly, you are trying to decompress the 6390 bytes of compressed data. That compressed data is a raw deflate stream, which has no zlib header or trailer. For that you would need to use inflateInit2(&stream, -MAX_WBITS) instead of inflateInit(&stream). The -MAX_WBITS requests decompression of raw deflate.
Zip-Utils
std::vector<unsigned char> inputBuffer;
std::vector<unsigned char> outBuffer(1024 * 1024);
HZIP hz = OpenZip(&inputBuffer[0], inputBuffer.capacity(), 0);
ZIPENTRY ze;
GetZipItem(hz, 0, &ze);
UnzipItem(hz, 0, &outBuffer[0], 1024 * 1024);
outBuffer.resize(ze.unc_size);
If inputBuffer contains a pkzip file, this snippet will unzip it and store contents in outBuffer.
That is all.

Why it reads the file correctly only at second time

I have a file which first 64 bytes are:
0x00: 01 00 00 10 00 00 00 20 00 00 FF 03 00 00 00 10
0x10: 00 00 00 10 00 00 FF 03 00 00 00 10 00 00 FF 03
0x20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
When i'm reading the file (mode read and write) at position 26 for 4 bytes I get 0 and the next time (at position 30) i get correctly 4096.
The code is:
// read LastDirectoryBlockStartByte...
seekg(26);
char * pCUIBuffer = new char[4];
read(pCUIBuffer, 4);
const unsigned int x1 = gcount ();
const unsigned int LastDirectoryBlockStartByte = *(unsigned int *)pCUIBuffer;
// read LastDirectoryBlockNumberItems...
seekg(30);
read(pCUIBuffer, 4);
const unsigned int x2 = gcount ();
const unsigned int LastDirectoryBlockNumberItems = *(unsigned int *)pCUIBuffer;
With gcount() I checked the bytes are read - and this were correctly both times 4.
I have no idea to debug it.
---------- EDIT ----------
When I use the following code (with some dummy before) it reads correctly:
char * pCUIBuffer = new char[4];
seekg(26);
read(pCUIBuffer, 4);
const unsigned int x1 = gcount ();
seekg(26);
read(pCUIBuffer, 4);
const unsigned int x2 = gcount ();
const unsigned int LastDirectoryBlockStartByte = *(unsigned int *)pCUIBuffer;
// read LastDirectoryBlockNumberItems...
seekg(30);
read(pCUIBuffer, 4);
const unsigned int x3 = gcount ();
const unsigned int LastDirectoryBlockNumberItems = *(unsigned int *)pCUIBuffer;
The difficulty is that the code stands at the begining in a methode. And the "false readed value" has obviously nothing to do with the listed code. Maybe theres a trick with flush or sync (but both I tryed...) or somewhat else...
You are saying that pCUIBuffer contains a pointer:
*(unsigned int *)pCUIBuffer;
And then you go get whatever it's pointing at...in RAM. That could be anything.
Now I'm writing an answer, because my attempt to contact TonyK failes (I asked for writing an answer).
The perfect answer to my question was to enable exceptions by calling exceptions (eofbit | failbit | badbit).
Rumo