I am reusing some old code(originally developed on c, not c++) with some functions to open/read/manipulate text-files. The path to the text-files is passed to the functions as a string (char*) then opened using: FileToUse = fopen(filename, "rb"); then multiple calls to fread() and fseek() are used. This code is known to work for external text-files, but now I would like to include the textfiles as resources in my project (MFC C++ in visual studio).
I found some examples on the web on how to use resources rusulting in this code:
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(IDR_TEXTFILE1), "TEXTFILE");
if (hResource){
HGLOBAL hLoadedResource = LoadResource(hInst, hResource);
if (hLoadedResource){
const char* pResource = LockResource(hLoadedResource);
if (pResource){
DWORD dwResourceSize = SizeofResource(hInst, hResource);
if (0 != dwResourceSize){ // if(FileToUse){
memcpy(&Buffer, pResource, (15 * 2)); // fread($Buffer, 15, 2, FileToUse);
pTemp = pResource + 200; // fseek(FileToUse, 200, SEEK_SET);
pTemp = pTemp + 100; // fseek(FileToUse, 100, SEEK_CUR);
pTemp = pResource + (dwResourceSize - 1) - 40; // fseek(FileToUse, -40, SEEK_END);
}
}
}
}
I replaced the fread call by memcpy() as shown, but I'm missing the return value of fread (actual read items) and in the original code the filepointer was moved by fseek, I wonder whether my approach using a temporary pointer is correct.
My ultimate goal is to simulate the fread and fseek calls for resources with similar function prototypes:
size_t resread( void* buffer, size_t size, size_t count, char* resource );
int resseek( char* resource, long offset, int origin );
Any suggestions are much appreciated.
Thanks for your help, based on the Agent_L's suggestion this is what I came up with:
Text-resource type:
struct _resource {
const char * content; // File content
size_t size; // File size
size_t ptrloc; // 'Pointer' location
};
typedef struct _resource RES_TXT;
resread based on fread:
size_t resread( void* buffer, size_t size, size_t count, RES_TXT * resource)
{
size_t actualCount = ( resource->size - resource->ptrloc ) / size;
actualCount = min( count, actualCount );
if ( actualCount <= 0 ) return 0;
memcpy(buffer, (resource->_ptr + resource->ptrloc), (actualCount * size) );
resource->ptrloc += (actualCount * size);
return actualCount;
}
and to complete resseek based on fseek:
int resseek( RES_TXT * resource, long offset, int origin ) {
size_t nextloc;
switch ( origin ) {
case SEEK_SET: nextloc = 0;
break;
case SEEK_CUR: nextloc = resource->ptrloc;
break;
case SEEK_END: nextloc = resource->size;
break;
default: return -1;
}
nextloc += offset;
if ( nextloc >= 0 && nextloc < resource->size )
resource->ptrloc = nextloc;
else
return -1;
return 0;
}
Any call to fseek and fread can now be replaced to use a resource instead of an external file.
The file handle contains not only the data but also it's length and current position. You have to duplicate that.
(handwirtten code, unproven):
struct resFile
{
char* pData;
int iLenght;
int iCurrPosition;
};
size_t resread( void* buffer, size_t size, size_t count, resFile* resource)
{
int ActualRead = min(size*count, resource->iLenght - resource->iCurrPosition);
memcpy(buffer, resource->pData + resource->iCurrPosition, ActualRead);
resource->iCurrPostion += ActualRead;
return ActualRead;
}
Let me notify you that fread shifts current file position. This means that you don't need invoke fseek each time. From this perspective may be you code can avoid implementation of resseek by simple increasing Buffer pointer
Related
I want to compress/decompress a unsigned char buffer using fast-LZMA2 by 7Zip : https://github.com/conor42/fast-lzma2
In the sample there's two function :
static int compress_file(FL2_CStream *fcs)
{
unsigned char in_buffer[8 * 1024];
unsigned char out_buffer[4 * 1024];
FL2_inBuffer in_buf = { in_buffer, sizeof(in_buffer), sizeof(in_buffer) };
FL2_outBuffer out_buf = { out_buffer, sizeof(out_buffer), 0 };
size_t res = 0;
size_t in_size = 0;
size_t out_size = 0;
do {
if (in_buf.pos == in_buf.size) {
in_buf.size = fread(in_buffer, 1, sizeof(in_buffer), fin);
in_size += in_buf.size;
in_buf.pos = 0;
}
res = FL2_compressStream(fcs, &out_buf, &in_buf);
if (FL2_isError(res))
goto error_out;
fwrite(out_buf.dst, 1, out_buf.pos, fout);
out_size += out_buf.pos;
out_buf.pos = 0;
} while (in_buf.size == sizeof(in_buffer));
do {
res = FL2_endStream(fcs, &out_buf);
if (FL2_isError(res))
goto error_out;
fwrite(out_buf.dst, 1, out_buf.pos, fout);
out_size += out_buf.pos;
out_buf.pos = 0;
} while (res);
fprintf(stdout, "\t%ld -> %ld\n", in_size, out_size);
return 0;
error_out:
fprintf(stderr, "Error: %s\n", FL2_getErrorName(res));
return 1;
}
static int decompress_file(FL2_DStream *fds)
{
unsigned char in_buffer[4 * 1024];
unsigned char out_buffer[8 * 1024];
FL2_inBuffer in_buf = { in_buffer, sizeof(in_buffer), sizeof(in_buffer) };
FL2_outBuffer out_buf = { out_buffer, sizeof(out_buffer), 0 };
size_t res;
size_t in_size = 0;
size_t out_size = 0;
do {
if (in_buf.pos == in_buf.size) {
in_buf.size = fread(in_buffer, 1, sizeof(in_buffer), fout);
in_size += in_buf.size;
in_buf.pos = 0;
}
res = FL2_decompressStream(fds, &out_buf, &in_buf);
if (FL2_isError(res))
goto error_out;
/* Discard the output. XXhash will verify the integrity. */
out_size += out_buf.pos;
out_buf.pos = 0;
} while (res && in_buf.size);
fprintf(stdout, "\t%ld -> %ld\n", in_size, out_size);
return 0;
error_out:
fprintf(stderr, "Error: %s\n", FL2_getErrorName(res));
return 1;
}
But I have no idea how to make it work with a buffer and also without size limit like 8*1024
like zlib deflate compression.
I want something like
LZMA2_Compress(void* buffer,size_t bufferSize);
and LZMA2_Decompress(void* buffer,size_t bufferSize);
I want to use this algorithm on some heavy files and Fast LZMA2 is the fastest high ratio compression I found, Please don't suggest me using other methods.
Here's my test code, It's working but just need to correct information:
https://gist.github.com/Bit00009/3241bb66301f8aaba16074537d094e61
Check the header file for all of the functions available. This one looks like the one you need. You will need to cast your buffers as (void *).
High level functions
fast-lzma2.h
...
/*! FL2_compress() :
* Compresses `src` content as a single LZMA2 compressed stream into already allocated `dst`.
* Call FL2_compressMt() to use > 1 thread. Specify nbThreads = 0 to use all cores.
* #return : compressed size written into `dst` (<= `dstCapacity),
* or an error code if it fails (which can be tested using FL2_isError()). */
FL2LIB_API size_t FL2LIB_CALL FL2_compress(void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
int compressionLevel);
...
Management of memory and options
To do explicit memory management (set dictionary size, buffer size, etc.) you need to create a context:
fast-lzma2.h
/*= Compression context
* When compressing many times, it is recommended to allocate a context just once,
* and re-use it for each successive compression operation. This will make workload
* friendlier for system's memory. The context may not use the number of threads requested
* if the library is compiled for single-threaded compression or nbThreads > FL2_MAXTHREADS.
* Call FL2_getCCtxThreadCount to obtain the actual number allocated. */
typedef struct FL2_CCtx_s FL2_CCtx;
FL2LIB_API FL2_CCtx* FL2LIB_CALL FL2_createCCtx(void);
than you can use FL2_CCtx_setParameter() to set the parameters in the context. The possible values for the paramters are listed in FL2_cParameter , and the value FL2_p_dictionarySize will allow you to set the dictionary size.
/*! FL2_CCtx_setParameter() :
* Set one compression parameter, selected by enum FL2_cParameter.
* #result : informational value (typically, the one being set, possibly corrected),
* or an error code (which can be tested with FL2_isError()). */
FL2LIB_API size_t FL2LIB_CALL FL2_CCtx_setParameter(FL2_CCtx* cctx, FL2_cParameter param, size_t value);
Finally you can compress the buffer by calling FL2_compressCCtx()
/*! FL2_compressCCtx() :
* Same as FL2_compress(), but requires an allocated FL2_CCtx (see FL2_createCCtx()). */
FL2LIB_API size_t FL2LIB_CALL FL2_compressCCtx(FL2_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
int compressionLevel);
I have some constraints where the addon is built with nan.h and v8 (not the new node-addon-api).
The end function is a part of a library. It accepts std::vector<char> that represents the bytes of an image.
I tried creating an image buffer from Node.js:
const img = fs.readFileSync('./myImage.png');
myAddonFunction(Buffer.from(img));
I am not really sure how to continue from here. I tried creating a new vector with a buffer, like so:
std::vector<char> buffer(data);
But it seems like I need to give it a size, which I am unsure how to get. Regardless, even when I use the initial buffer size (from Node.js), the image fails to go through.
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
[1] 16021 abort (core dumped)
However, when I read the image directly from C++, it all works fine:
std::ifstream ifs ("./myImage.png", std::ios::binary|std::ios::ate);
std::ifstream::pos_type pos = ifs.tellg();
std::vector<char> buffer(pos);
ifs.seekg(0, std::ios::beg);
ifs.read(&buffer[0], pos);
// further below, I pass "buffer" to the function and it works just fine.
But of course, I need the image to come from Node.js. Maybe Buffer is not what I am looking for?
Here is an example based on N-API; I would also encourage you to take a look similar implementation based on node-addon-api (it is an easy to use C++ wrapper on top of N-API)
https://github.com/nodejs/node-addon-examples/tree/master/array_buffer_to_native/node-addon-api
#include <assert.h>
#include "addon_api.h"
#include "stdio.h"
napi_value CArrayBuffSum(napi_env env, napi_callback_info info)
{
napi_status status;
const size_t MaxArgExpected = 1;
napi_value args[MaxArgExpected];
size_t argc = sizeof(args) / sizeof(napi_value);
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
assert(status == napi_ok);
if (argc < 1)
napi_throw_error(env, "EINVAL", "Too few arguments");
napi_value buff = args[0];
napi_valuetype valuetype;
status = napi_typeof(env, buff, &valuetype);
assert(status == napi_ok);
if (valuetype == napi_object)
{
bool isArrayBuff = 0;
status = napi_is_arraybuffer(env, buff, &isArrayBuff);
assert(status == napi_ok);
if (isArrayBuff != true)
napi_throw_error(env, "EINVAL", "Expected an ArrayBuffer");
}
int32_t *buff_data = NULL;
size_t byte_length = 0;
int32_t sum = 0;
napi_get_arraybuffer_info(env, buff, (void **)&buff_data, &byte_length);
assert(status == napi_ok);
printf("\nC: Int32Array size = %d, (ie: bytes=%d)",
(int)(byte_length / sizeof(int32_t)), (int)byte_length);
for (int i = 0; i < byte_length / sizeof(int32_t); ++i)
{
sum += *(buff_data + i);
printf("\nC: Int32ArrayBuff[%d] = %d", i, *(buff_data + i));
}
napi_value rcValue;
napi_create_int32(env, sum, &rcValue);
return (rcValue);
}
The JavaScript code to call the addon
'use strict'
const myaddon = require('bindings')('mync1');
function test1() {
const array = new Int32Array(10);
for (let i = 0; i < 10; ++i)
array[i] = i * 5;
const sum = myaddon.ArrayBuffSum(array.buffer);
console.log();
console.log(`js: Sum of the array = ${sum}`);
}
test1();
The Output of the code execution:
C: Int32Array size = 10, (ie: bytes=40)
C: Int32ArrayBuff[0] = 0
C: Int32ArrayBuff[1] = 5
C: Int32ArrayBuff[2] = 10
C: Int32ArrayBuff[3] = 15
C: Int32ArrayBuff[4] = 20
C: Int32ArrayBuff[5] = 25
C: Int32ArrayBuff[6] = 30
C: Int32ArrayBuff[7] = 35
C: Int32ArrayBuff[8] = 40
C: Int32ArrayBuff[9] = 45
js: Sum of the array = 225
I'm using openssl library to implement an ETSI standard and, more specifically, to realize communications with a PKI.
To do that I must use the ECIES encryption scheme but it isn't implemented in openssl.
I have found this piece of code here in the crypto++ google group:
int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group((EC_KEY*)m_pPrivKey));
EC_KEY* temp_key = EC_KEY_new_by_curve_name(curve_id);
size_t uPubLen = i2o_ECPublicKey((EC_KEY*)m_pPrivKey, NULL);
o2i_ECPublicKey(&temp_key, (const byte**)&pCiphertext, uPubLen); // warnign this moves the pCiphertext pointer
uCiphertextSize -= uPubLen;
size_t SecLen = (EC_GROUP_get_degree(EC_KEY_get0_group((EC_KEY*)m_pPrivKey)) + 7) / 8;
byte* pSec = new byte[SecLen];
int ret = ECDH_compute_key(pSec, SecLen, EC_KEY_get0_public_key(temp_key), (EC_KEY*)m_pPrivKey, NULL);
ASSERT(ret == SecLen);
EC_KEY_free(temp_key);
CHashFunction GenFx(CHashFunction::eSHA1); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
uPlaintextSize = (uCiphertextSize > GenFx.GetSize()) ? (uCiphertextSize - GenFx.GetSize()) : 0;
int mac_key_len = 16;
int GenLen = uPlaintextSize + mac_key_len;
uint32 counter = 1;
CBuffer GenHash;
while(GenHash.GetSize() < GenLen)
{
GenFx.Add(pSec, SecLen);
CBuffer Buff;
Buff.WriteValue<uint32>(counter++, true);
GenFx.Add(&Buff);
GenFx.Finish();
GenHash.AppendData(GenFx.GetKey(), GenFx.GetSize());
GenFx.Reset();
}
GenHash.SetSize(GenLen); // truncate
delete pSec;
byte* key = GenHash.GetBuffer();
byte* macKey = key + uPlaintextSize;
unsigned char* result;
size_t mac_len = uCiphertextSize - uPlaintextSize;
ASSERT(mac_len == 20);
byte* mac_result = new byte[mac_len];
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, macKey, mac_key_len, EVP_sha1(), NULL);
HMAC_Update(&ctx, pCiphertext, uPlaintextSize);
HMAC_Final(&ctx, mac_result, &mac_len);
HMAC_CTX_cleanup(&ctx);
Ret = memcmp(pCiphertext + uPlaintextSize, mac_result, mac_len) == 0 ? 1 : 0;
delete mac_result;
ASSERT(pPlaintext == NULL);
pPlaintext = new byte[uPlaintextSize];
for(int i=0; i < uPlaintextSize; i++)
pPlaintext[i] = pCiphertext[i] ^ key[i];
But I am not sure that it works correctly and I don't know how use this piece of code.
Have anyone already implemented this scheme?
My goal is to understand stack unwinding in 64-bit PE32+ executable format in Windows, or how the following API can calculate addresses of a function prologue, body, epilogue, etc.:
CONTEXT context = {0};
RtlCaptureContext(&context);
DWORD64 ImgBase = 0;
RUNTIME_FUNCTION* pRTFn = RtlLookupFunctionEntry(context.Rip, &ImgBase, NULL);
_tprintf(L"Prologue=0x%p\n", (void*)(ImgBase + pRTFn->BeginAddress));
I know that the information on the offsets of all non-leaf functions used by the linker is included in the PE32+ header in the exceptions directory. So I tried to write my own function to parse it. I got to this point where I got stumped:
//INFO -- must be compiled as x64 only!
void GetFunctionTable(BYTE* lpBaseAddress, size_t szImageSz)
{
if(lpBaseAddress)
{
if(szImageSz > sizeof(IMAGE_DOS_HEADER))
{
IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)lpBaseAddress;
if(pDOSHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
IMAGE_NT_HEADERS* pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDirectories = NULL;
if(pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{
//64-bit image only
IMAGE_NT_HEADERS64* pHdr64 = (IMAGE_NT_HEADERS64*)pNtHeader;
IMAGE_OPTIONAL_HEADER64* pIOH64 = &pHdr64->OptionalHeader;
pDataDirectories = pIOH64->DataDirectory;
IMAGE_DATA_DIRECTORY* pExceptDir = &pDataDirectories[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
if(pExceptDir->VirtualAddress &&
pExceptDir->Size)
{
IMAGE_RUNTIME_FUNCTION_ENTRY* pRFs = (IMAGE_RUNTIME_FUNCTION_ENTRY*)
GetPtrFromRVA64(pExceptDir->VirtualAddress, pNtHeader, lpBaseAddress);
//'pRFs' = should point to an array of RUNTIME_FUNCTION structs
// but in my case it points to an empty region of memory with all zeros.
}
}
}
}
}
}
with the following helper functions:
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader64(DWORD_PTR rva, PIMAGE_NT_HEADERS64 pNTHeader)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned int i;
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + section->Misc.VirtualSize)))
return section;
}
return 0;
}
LPVOID GetPtrFromRVA64(DWORD rva, const void* pNTHeader, const void* imageBase)
{
PIMAGE_SECTION_HEADER pSectionHdr;
INT_PTR delta;
pSectionHdr = GetEnclosingSectionHeader64( rva, (PIMAGE_NT_HEADERS64)pNTHeader );
if ( !pSectionHdr )
return 0;
delta = (INT_PTR)(pSectionHdr->VirtualAddress - pSectionHdr->PointerToRawData);
return (PVOID) ( (BYTE*)imageBase + rva - delta );
}
So I'm testing it on the self executable:
HMODULE hMod = ::GetModuleHandle(NULL);
MODULEINFO mi = {0};
if(::GetModuleInformation(::GetCurrentProcess(), hMod, &mi, sizeof(mi)))
{
GetFunctionTable((BYTE*)hMod, mi.SizeOfImage);
}
But the problem is that inside my GetFunctionTable when I try to look up the function table mapped in memory in the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory, I'm getting a pointer (i.e. IMAGE_RUNTIME_FUNCTION_ENTRY*) to an empty region of memory. I must be not translating the rva address correctly.
So anyone who knows how PE32+ header is mapped in memory, can please show what am I doing wrong there?
I try to resolve the circuit satisfiability problem reading the circuit from file (in the form presented in text visualizer-somehow dynamic). If my circuit is small my resolver work smooth (small means like <16-18 wires). If i get to 25-30 wires so 2^25-30 possibilities i encountered a problem with a violation of access. I tried to free memory every time i can. I tried to create a new pointer of my expression every time, but the access violation always occur.
^ How is this possible ?
int evalBoolExprForBinaryVector(char *expr, int n, int binaryVector[]){
// create boolean expression from logical expression
char* expression = (char*) malloc(sizeof(char) * strlen(expr) + 1);
strcpy(expression, expr);
for(int binaryVectorCounter=0; binaryVectorCounter<n; binaryVectorCounter++){
char* currentSearchedIdentifier = (char*) malloc(sizeof(char) * 10);
char* index =(char*) malloc(sizeof(char) * 10);
char* valueOfIndex = (char*) malloc(sizeof(char)*2);
strcpy(currentSearchedIdentifier,"v[");
sprintf(index, "%d", binaryVectorCounter);
strcat(currentSearchedIdentifier, index);
strcat(currentSearchedIdentifier, "]");
sprintf(valueOfIndex, "%d", binaryVector[binaryVectorCounter]);
expression = str_replace(expression,currentSearchedIdentifier,valueOfIndex);
free(currentSearchedIdentifier);
free(index);
free(valueOfIndex);
}
// here my expression will be something like
// ( 0 | 1 ) & (!0 | !1) & ...
// evaluate this
return evalBoolExpr(expression);
};
Here is my code for better understanding.
The program breaks with this exception in strlen.asm at:
main_loop:
mov eax,dword ptr [ecx] ; read 4 bytes
Thanks in advance for any thoughts.
I rewrite this part in c++ manner and everything worked smooth (some delay but at least it can finish with success)
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
int evalBoolExprForBinaryVector(char *expr, int n, int binaryVector[]){
std::string expression(expr);
for(int binaryVectorCounter=0; binaryVectorCounter<n; binaryVectorCounter++){
std::string currentSearchedIdentifier, valueOfIndex;
currentSearchedIdentifier = "v[" + std::to_string(binaryVectorCounter) + "]";
valueOfIndex = std::to_string(binaryVector[binaryVectorCounter]);
replaceAll(expression,currentSearchedIdentifier,valueOfIndex);
}
char *cstr = new char[expression.length() + 1];
strcpy(cstr, expression.c_str());
return evalBoolExpr(cstr);
};