lzma is failed to createobjectfunc for rar using c++ - extract

There is failed to CreateObject by passing
rar(clsid = 23170F69-40C1-278A-1000-000110030000)
the lzma sdk is lzma1900. the testing dll(7zra.dll) is compiled by vs2008 nmake in "lzma1900\CPP\7zip\Bundles\Format7zR".
How to compile the lzma to extract .rar file? any idea is much appreciated.
it's ok by passing 7z(23170F69-40C1-278A-1000-000110070000).
DEFINE_GUID(CLSID_CFormatRar,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00);
#define kDllName "7zra.dll"
int MY_CDECL main(int numArgs, const char *args[])
{
NT_CHECK
NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
{
PrintError("Can not load 7-zip library");
return 1;
}
Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject");
if (!createObjectFunc)
{
PrintError("Can not get CreateObject");
return 1;
}
//the code context extracts from lzma1900\CPP\7zip\UI\Client7z\Client7z.cpp
//always failed if set rar
CMyComPtr<IInArchive> archive;
if (createObjectFunc(&CLSID_CFormatRar, &IID_IInArchive, (void **)&archive) != S_OK)
{
PrintError("Can not get class object");
return 1;
}
//...
}

figure it out.lzma sdk doesn't contain rar unpack code, 7z1900 source code is ok.
the target dll is complied from 7z1900\CPP\7zip\Bundles\Format7zF

Related

C++ How do I turn a string into a json object? [duplicate]

I'm currently working in C++, getting an HTTP response from a request that I write into a .txt file using ostream. This happens asynchronously and I don't want to change this.
Once the data is done being written, I want to read from the file
{"data":{"request":[{"type":"City","query":"London, United Kingdom"}],"weather":[{"date":"2013-04-21","astronomy".....
~somehow~ prettify the string using either an outside library like nlohmann/json or other(?) and then
a)print it to the console and
b) save it in a different file (pretty.json)
I am having trouble understanding which method to use from:
https://github.com/nlohmann/json
Any ideas how to approach this?
I was thinking getting the file line by line until I hit EOF into a sort of "buffer" and then running _json on that and saving the solution which can be displayed on the console...
My code so far
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <sstream>
#include "json.hpp"
using namespace utility; // string conversion
using namespace web; // URI
using namespace web::http; // HTTP commands
using namespace web::http::client; // HTTP Client features
using namespace concurrency::streams; // Asynch streams, like Node
using json = nlohmann::json;
int main()
{
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.txt"))
.then([=](ostream outFile)
{
*fileStream = outFile;
http_client client //gets the info
return client.request(methods::GET, stringBuilder.to_string());
})
.then([=](http_response response) // set up response handler
{
printf("Received response status code:%u\n", response.status_code());
return response.body().read_to_end(fileStream->streambuf());
})
.then([=](size_t) // close file stream
{
return fileStream->close();
})
.then([=]()
{
nlohmann::json j;
std::ifstream i;
i.open("results.txt"); // ?? <<< === this is where my question is
});
// Wait for all the outstanding I/O to complete, handle exceptions
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
}
return 0;
}
SOLUTION:
.then([=]()
{
// read a JSON file
std::ifstream readFromFile("results.txt");
if (readFromFile.is_open()) {
nlohmann::json j;
readFromFile >> j;
// write prettified JSON to another file
std::ofstream writeToFile("pretty.json");
writeToFile << std::setw(4) << j << std::endl;
readFromFile.close();
writeToFile.close();
}
else {
std::cout << "unable to open file";
}
});
You have two choices to prettify with nlohmann.
Uses dump which produces a string
int indent = 4;
nlohmann::json data;
data.dump(indent);
Or use the stream output overload with field width set
std::ofstream o("pretty.json");
o << std::setw(4) << data << std::endl;

Json parsing not working with JsonObject using ArduinoJson library

I am using the following code to store Config.json file to ESP32 flash memory using SPIFFS
#include <ArduinoJson.h>
#include <FS.h>
#include<SPIFFS.h>
bool loadConfig() {
File configFile = SPIFFS.open("/Config.json", "r");
if (!configFile) {
Serial.println("Failed to open config file");
return false;
}
size_t size = configFile.size();
if (size > 1024) {
Serial.println("Config file size is too large");
return false;
}
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
// We don't use String here because ArduinoJson library requires the input
// buffer to be mutable. If you don't use ArduinoJson, you may as well
// use configFile.readString instead.
configFile.readBytes(buf.get(), size);
Serial.println(buf.get());
StaticJsonBuffer<1024> jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
if (!json.success()) {
Serial.println("Failed to parse config file");
return false;
}
const char* ssid = json["ssid"];
const char* password = json["password"];
// Real world application would store these values in some variables for
// later use.
Serial.print("Loaded ssid: ");
Serial.println(ssid);
Serial.print("Loaded password: ");
Serial.println(password);
return true;
}
void setup() {
Serial.begin(115200);
Serial.println("");
delay(1000);
Serial.println("Mounting FS...");
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
if (!loadConfig()) {
Serial.println("Failed to load config");
}
else {
Serial.println("Config loaded");
}
}
void loop() {
yield();
}
However the parsing fails, and I get the following message on the serial monitor:
Mounting FS...
⸮xV⸮⸮⸮⸮⸮
Failed to parse config file
Failed to load config
My Arduino IDE version: 1.8.13 (Windows)
Config file has 2 objects:
{
"ssid": "ESP32",
"password": "Softronics"
}
Thank you in advance
There's no need to pre-allocate a buffer to store the file for ArduinoJSON. ArduinoJSON is quite capable of reading the file itself and avoiding the need to manage a buffer for the file.
This code is unnecessary. You should not allocate a buffer.
std::unique_ptr<char[]> buf(new char[size]);
// We don't use String here because ArduinoJson library requires the input
// buffer to be mutable. If you don't use ArduinoJson, you may as well
// use configFile.readString instead.
configFile.readBytes(buf.get(), size);
Serial.println(buf.get());
StaticJsonBuffer<1024> jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
if (!json.success()) {
Serial.println("Failed to parse config file");
return false;
}
Here's a complete program which works correctly for me:
#include <ArduinoJson.h>
#include <FS.h>
#include<SPIFFS.h>
bool loadConfig() {
File configFile = SPIFFS.open("/Config.json", "r");
if (!configFile) {
Serial.println("Failed to open config file");
return false;
}
size_t size = configFile.size();
if (size > 1024) {
Serial.println("Config file size is too large");
return false;
}
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, configFile);
if(error) {
Serial.println("Failed to parse config file");
return false;
}
const char* ssid = doc["ssid"];
const char* password = doc["password"];
// Real world application would store these values in some variables for
// later use.
Serial.print("Loaded ssid: ");
Serial.println(ssid);
Serial.print("Loaded password: ");
Serial.println(password);
return true;
}
void setup() {
Serial.begin(115200);
Serial.println("");
delay(1000);
Serial.println("Mounting FS...");
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
if (!loadConfig()) {
Serial.println("Failed to load config");
}
else {
Serial.println("Config loaded");
}
}
void loop() {
yield();
}
The code you posted was for ArduinoJSON version 5, which is obsolete. This uses ArduinoJSON version 6. You should upgrade your library to use it.
The ArduinoJSON documentation and examples are quite helpful when writing code that uses the library.
Also, please try indenting your code, at least as a courtesy to others if not to do yourself a favor. Proper indentation makes code much more readable.

how do i publish the data on mqtt of the bme680 sensor using ESP32cam

I am using windows 10 and working on getting the gas readings from BME680 using esp32cam. I tried to add this:
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
//#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Arduino_JSON.h>
//uint64_t mac;
//uint32_t high;
//uint32_t low;
// Replace the next variables with your SSID/Password combination
const char* ssid = "";
const char* password = "";
// Add your MQTT Broker IP address, example:
//const char* mqtt_server = "";
const char* mqtt_server = "";
const char* mqtt_port = "";
const char* mqtt_user = "";
const char* mqtt_password = "";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//uncomment the following lines if you're using SPI
#include <SPI.h>
#define BME_SCK 14
#define BME_MISO 12
#define BME_MOSI 13
#define BME_CS 15
//Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
float temperature = 0;
float humidity = 0;
float pressure = 0;
float gas = 0;
//Device ID
//uint64_t chip_id;
//chip_id=ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes).
// LED Pin
const int ledPin = 4;
void setup() {
Serial.begin(115200);
// default settings
// (you can also pass in a Wire library object like &Wire2)
//status = bme.begin();
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
WiFi.begin();
}
setup_wifi();
client.setServer(mqtt_server,...);
client.setCallback(callback);
pinMode(ledPin, OUTPUT);
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
if (String(topic) == "esp32/output") {
Serial.print("Changing output to ");
if(messageTemp == "on"){
Serial.println("on");
digitalWrite(ledPin, HIGH);
}
else if(messageTemp == "off"){
Serial.println("off");
digitalWrite(ledPin, LOW);
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
Serial.println("connected");
// Subscribe
client.subscribe("esp32/output");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(20000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 5000) {
lastMsg = now;
// Temperature in Celsius
temperature = bme.readTemperature();
// Uncomment the next line to set temperature in Fahrenheit
// (and comment the previous temperature line)
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit
// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
//Serial.print("Temperature: ");
//Serial.println(tempString);
//client.publish("esp32/temperature", tempString);
humidity = bme.readHumidity();
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
//Serial.print("Humidity: ");
//Serial.println(humString);
//client.publish("esp32/humidity", humString);
pressure = bme.readPressure();
//Convert the value to a char array
char preString[16];
dtostrf(pressure, 1, 2, preString);
//Serial.print("Pressure: ");
//Serial.println(preString);
//client.publish("esp32/pressure", preString);
gas = bme.readGas();
//Serial.print(bme.gas_resistance / 1000.0);
char gasString[8];
dtostrf(gas, 1, 2, gasString);
//Serial.println(" KOhms");
char macValue[13]; // Don't forget one byte for the terminating NULL...
uint64_t mac = ESP.getEfuseMac();
sprintf(macValue, "%012x", mac);
//Serial.print("ChipID: ");
//Serial.println(chipId);
//client.publish("esp32/chipid", chipId);
JSONVar data;
data["temperature"] = temperature;
data["humidity"] = humidity;
data["pressure"] = pressure;
data["macValue"] = macValue;
data["gas"] = gas;
//Serial.print("data.keys() = ");
//Serial.println(data.keys());
//Serial.print("Data = ");
//Serial.println(data);
String jsonString = JSON.stringify(data);
//Serial.print("JSON.stringify(data) = ");
//Serial.println(jsonString);
client.publish("esp32/data", jsonString.c_str());
}
}
everything got compiled perfectly. But when i tried to upload the code, this error came up:
Arduino: 1.8.9 (Windows 10), Board: "ESP32 Wrover Module, Huge APP
(3MB No OTA), QIO, 80MHz, 115200, Verbose"
Sketch uses 789282 bytes (25%) of program storage space. Maximum
is 3145728 bytes.
Global variables use 40652 bytes (12%) of dynamic memory, leaving
287028 bytes for local variables. Maximum is 327680 bytes.
esptool.py v2.6
Serial port COM7
Connecting.....
Chip is .....(revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse,
Coding Scheme None
MAC: .....
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Warning: Could not auto-detect Flash size (FlashID=0xffffff,
SizeID=0xff), defaulting to 4MB
Compressed 8192 bytes to 47...
A fatal error occurred: Timed out waiting for packet content
A fatal error occurred: Timed out waiting for packet content
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I don't know why is this thing coming up because previously everything was working fine when I tried to incorporate BME280 and publish the available data on MQTT. Now, I have switched to bme680.
EDIT:
I tried to disconnect BME from ESP32, then uploaded the code, then connected BME back. The error did not show up, but still, the data is not being shown this time, rather something like this, continually:
rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun 8 2016 00:22:57
It looks to me that ESP32-CAM is not in the bootloader mode when you try to upload the code.
Did you connect IO0 and GND pins and push the reset button?
You should see the message that ESP32 is ready for upload in the terminal window.
Sorry for the late reply ... :)

Parsing data from incoming HTTP Post request on ESP8266/Wemos

I'm sending an HTTP Post request on my Android App to my Wemos D1 mini pro and want to parse the incoming data (which is a json). My current code just prints out the whole POST request and I need to trim it so I only get the needed data. There are several examples out there but nothing matched my needs or worked at all.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
const char* ssid = "myssid";
const char* password = "mypassword";
char c;
String readString = String(100);
WiFiServer wifiServer(80);
void setup() {
Serial.begin(9600);
delay(1000);
WiFi.begin(ssid, password);
WiFi.mode(WIFI_STA);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting..");
}
Serial.print("Connected to WiFi. IP:");
Serial.println(WiFi.localIP());
wifiServer.begin();
}
//for parsing the actual JSON later
//you can ignore this at this moment because I don't even get the needed string to parse it from JSON
void handleReceivedMessage(String message){
StaticJsonBuffer<500> JSONBuffer; //Memory pool
JsonObject& parsed = JSONBuffer.parseObject(message); //Parse message
if (!parsed.success()) { //Check for errors in parsing
Serial.println("Parsing failed");
return;
}
const char * name3 = parsed["name"]; //Get name from HTTP
Serial.println("name3");
}
void loop() {
WiFiClient client = wifiServer.available();
if (client) {
Serial.println("Client connected");
while (client.connected()) {
while (client.available()>0) {
//instream from mobile device
char c = client.read();
if (readString.length() < 100) {
//store characters to string
readString.concat(c);
//Serial.print(c);
}
Serial.print(c);
//if HTTP request has ended
if (c == '\n') {
//Serial.println(readString);
delay(50);
//handleReceivedMessage(readString);
readString = "";
client.stop();
}
}}}}
Well first of all you seem to be using ArduinoJson lib version 5, now I could share the code I worked with and never failed me with version 5. But i'm going to encourage you to update the library to version 6 and share with you my piece of code.
I use this normally when I need to get information out of API's
DynamicJsonDocument doc(1024);
char* payload1 = (char*)malloc(http.getSize() + 1);
http.getString().toCharArray(payload1, http.getSize() + 1);
Serial.println(payload1);
http.end();
auto error = deserializeJson(doc, payload1);
free(payload1);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
return;
}
serializeJsonPretty(doc, Serial);
now as you can see, I'm using a getString method from httpClient lib in order to fill my char array and than parse it into json object (pretty much the same thing you was attempting, only difference is the memory pointers and Memory allocations.
Hopefully this will work with you.

How to read AddressOfEntryPoint in memory

I am working to analyze malware, this malware try to write a new file to other process. they save the data of the new file in memory start with MZ.
how I can know the address of entry point for the PE file in memory?
Find below way to find address of entry point as well as to read various header parameters.
LPCSTR fileName; //exe file to parse
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS peHeader;
hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\n CreateFile failed in read mode \n");
return 1;
}
hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hFileMapping==0)
{
printf("\n CreateFileMapping failed \n");
CloseHandle(hFile);
return 1;
}
lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
if(lpFileBase==0)
{
printf("\n MapViewOfFile failed \n");
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}
dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; //pointer to dos headers
if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE)
{
//if it is executable file print different fileds of structure
//dosHeader->e_lfanew : RVA for PE Header
printf("\n DOS Signature (MZ) Matched");
//pointer to PE/NT header
peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew);
if(peHeader->Signature==IMAGE_NT_SIGNATURE)
{
printf("\n PE Signature (PE) Matched \n");
//address of entry point
//peHeader->OptionalHeader.AddressOfEntryPoint
}
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 0;
}
else
{
printf("\n DOS Signature (MZ) Not Matched \n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}