I used FFMPEg codes in my app, where I need to get FLV packets for my program. For this I use avcodec_encode_video2(). My problem is that function creates AVPacket packet, which does not keep a full FLV format, only its body. But I need still its header. Usually another function (av_write_frame()) makes it. I cannot use av_write_frame() in my app, because it does not fit my requirement. So maybe anybody knows a function in ffmpeg library, which could add FLV header to the created packets by avcodec_encode_video2().
The FLV header by itself is relatively simple.
It can be modelized with the following code:
/* FLV file header */
#define FLV_SIGNATURE "FLV"
#define FLV_VERSION ((uint8)0x01)
#define FLV_FLAG_VIDEO ((uint8)0x01)
#define FLV_FLAG_AUDIO ((uint8)0x04)
typedef struct __flv_header {
uint8_t signature[3]; /* always "FLV" */
uint8_t version; /* should be 1 */
uint8_t flags;
uint32_t offset; /* always 9 */
} flv_header;
The flags field is a bitmask telling whether the file possesses video, audio, or both streams. For example, if your file has audio and video, its value will be 5.
Be careful that the offset field is encoded in big-endian, which on little-endian platforms is represented by the value 150994944.
If you do not wish to use such a structure, and have a way to directly write a buffer, you can create it like this:
uint_8 buffer[9] = {0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, 0x09};
Related
It seems the value returned by CryptStringToBinary() in pdwSkip parameter is wrong.
The documentation says:
pdwSkip - a pointer to a DWORD value that receives the number of
characters skipped to reach the beginning of the actual base64 or
hexadecimal strings.
char buf[100]={0};
DWORD bufSize=sizeof(buf);
DWORD skip=0, flags=0;
BOOL rv=CryptStringToBinary("\r\n\t c3Nzc3Nzcw==\r\n\t ",0,CRYPT_STRING_BASE64,
buf,&bufSize,&skip,&flags);
if(rv) {
printf("skip=%u\n",skip);
}
The code prints:skip=0I expected it to be 4 because "the actual base64 string" is "c3Nzc3Nzcw==". And before it there are 4 characters.I tested it on Windows 8.1 with latest updates.
You are passing CRYPT_STRING_BASE64 in the third param - that means there are no headers.
If you pass CRYPT_STRING_BASE64HEADER instead, the function will interpret your string as PEM encoded data. PEM looks like this:
------ BEGIN STUFF --------------
AAAAAAAAABBBBBBBBBBBBBBBBBCCCCCCD
GGGGGGGGGGGaaaaaaaaaaaaasss666666
------ END STUFF---------
I'm not sure what exactly is the heuristic that the function uses to detect the header (probably a sequence of dashes, followed by some ASCII, followed by more dashes, then EOL), but "\r\n\t " is definitely not a reasonable header in a PEM encoded crypto object. Those are valid Base64 characters. The docs make a reference to "certificate beginning and ending headers" - that's a very specific thing, the PEM header/footer lines.
Not sure if the function is designed to quietly skip whitespace between Base64 characters, the docs are silent on that. That said, quietly skipping whitespace is pretty much a requirement for any PEM friendly Base64 decoder. PEM includes whitespace (the newlines) by design. But they definitely don't count that whitespace as a header. For one thing, whitespace in PEM occurs in the middle.
After you add the the beginning of the actual base64, you will receive the number of skipped characters.
Try this:
#include <Windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <vector>
#pragma comment(lib,"Crypt32.lib")
int main()
{
LPCSTR szPemPublicKey =
"\r\n\t "
"-----BEGIN CERTIFICATE -----"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRLhZXK29Xo5YdSoMdAe"
"MHwDYAmThPSJzbQaBhVLCY1DTQr0JRkvd+0xfdwih97bWUXVpxuOgYH9hofIzZGP"
"-----END CERTIFICATE -----";
BYTE derPrivateKey[2048];
char buf[1024] = { 0 };
DWORD bufSize = sizeof(buf);
DWORD skip = 0, flags = 0;
BOOL rv = CryptStringToBinary(szPemPublicKey, 0, CRYPT_STRING_BASE64HEADER,
derPrivateKey, &bufSize, &skip, &flags);
if (rv) {
printf("skip=%u\n", skip);
}
}
Debug:
When you store a file in OneDrive, an :ms-properties alternate data stream is added. I opened an example stream using FlexHex (as shown in the image), but I can't tell what type of structure those bytes might represent. Does anyone know?
Actually, based on the 1SPS sequence, I think it might be a prop store or a shell bag or something. For reference. And this. But I'm not sure if that's right.
They are just serialized Windows properties. You can write and read these files (as streams) using builtin Windows implementation of IPropertyStore, for example using the PSCreateMemoryPropertyStore function
Here is a small sample console app that creates a test.props file with one property of string type:
#include <windows.h>
#include <atlbase.h>
#include <atlcom.h>
#include <propsys.h>
#include <propkey.h>
#include <propvarutil.h>
// some COM error handling useful macros
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#define SBTRACE wprintf
#define CHECKHR(expr) {hr=(expr);if(FAILED(hr)){ SBTRACE(L"HR FAILED line:%u file:%s\n", __LINE__, __WFILE__); goto cleanup; } }
#define HR HRESULT hr=S_OK;
int main()
{
HR;
PROPVARIANT pv;
PropVariantInit(&pv);
CoInitialize(NULL);
{
CComPtr<IPropertyStore> ps;
CComPtr<IPersistStream> pstream;
CComPtr<IStream> stream;
// create the in-memory store
CHECKHR(PSCreateMemoryPropertyStore(IID_PPV_ARGS(&ps)));
// define some PROPVARIANT value (here it's a string)
CHECKHR(InitPropVariantFromString(L"hello world", &pv));
// any property key would work
CHECKHR(ps->SetValue(PKEY_ItemNameDisplay, pv));
// get IPersistStream to be able to load or write
CHECKHR(ps->QueryInterface(&pstream));
// create a file stream
CHECKHR(SHCreateStreamOnFileEx(L"test.props", STGM_WRITE | STGM_CREATE, 0, TRUE, nullptr, &stream));
// this sample only saves, but you can load from an existing stream
CHECKHR(pstream->Save(stream, TRUE));
}
cleanup:
PropVariantClear(&pv);
CoUninitialize();
return 0;
}
Here is the result:
1SPS is the signature for a serialized property store, which is essentially a key value pair type system. its a standard structure, so its easy to parse, although the data types can make it a bit of a challenge.
It looks like there are some GUIDs in there among the 4 or so. it would be easy enough to parse out those structures as similar things are used in shellbags. it certainly just looks like a series of 1sps blocks which makes it easy.
you already know my email, so if you can extract out a few of these ADS examples, zip them, and send, i can take a closer look. if its warranted, ill even write a new forensic tool to parse them
I'm creating a 4 bit and 8 bit colour encoding for font. This includes a foreground, background, style, and format. My hope is to use the following struct to represent the data in a 4-byte pack. My intent is to extract it as a single uint32_t that can be converted to binary data and saved in a file.
This is what I currently have:
struct font_pack {
uint8_t : 8;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t foreground;
uint8_t background;
}
The header contains two half-bytes. format says the colour codes are either 4-bit or 8-bit colour. style is a bit flag set that declares formatter such as bolding and underline.
I am then using the following union to get the raw binary for both writing to file, as well to set or print the data as hex.
union font_raw {
font_pack pack;
uint32_t data;
}
Unfortunately when I print out the hex I get 0x04032100 when I was expecting 0x00120304. Which makes me feel like byte alignment is not guaranteed within a union and endianness is catching me. I was really just hoping to have simple method of packing and unpacking the data into 3 bytes.
Is there any other easy way to do it or am I stuck with making a more traditional function that does the packing and unpacking?
This looks like an endianness issue, for sure. I'm guessing you're on x86/x64 (Intel-like) architecture, which is little-endian and will pack bytes from least-significant to most significant. Provided you are writing and reading the data on the same architecture (so little-endian systems) the endianness will ensure you get byte packing read back in the same order, so your font_pack members should still come out correctly. However if you'll be loading these files on a big-endian system you'll need to go the more traditional route. But if you're on the same endian-ness guaranteed, I'd go with your method. It's nicely elegant :)
edit: If you are reading or writing between different endianness machines, then you could always do something like the following:
#ifdef LITTLE_ENDIAN
struct font_pack {
uint8_t : 8;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t foreground;
uint8_t background;
}
#else
struct font_pack {
uint8_t background;
uint8_t foreground;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t : 8;
}
#endif
And then define LITTLE_ENDIAN on your x86 or similar system, and not on the big-endian system. Hope that helps.
I am using Veins3.0 with SUMO-0.21.0 and omnetpp4.4.
I tried to use the vehicle tracking command in TraCI/SUMO. It is described here: http://sumo.dlr.de/wiki/TraCI/Change_GUI_State.
There you can read that the Variable View ID Type of the value New Value for this command are 0xa6 "View #0" string <vehicle id>.
So I wrote a new function in TraCICommandInterface.cc to track a vehicle.
void TraCICommandInterface::setVehicleTracking(std::string nodeId) {
uint8_t variableId = VAR_TRACK_VEHICLE;
uint8_t variableType = TYPE_STRING;
TraCIBuffer buf = connection.query(CMD_SET_GUI_VARIABLE, TraCIBuffer() << variableId << "View #0" << variableType << nodeId);
ASSERT(buf.eof());
}
I used some constants from TraCIConstants.h
// track vehicle
#define VAR_TRACK_VEHICLE 0xa6
// command: set GUI variable
#define CMD_SET_GUI_VARIABLE 0xcc
// 8 bit ASCII string
#define TYPE_STRING 0x0C
The function is called from TraCIMobility.h, which fills the node id with getExternalID().
void commandTrackVehicle(){
getCommandInterface()->setVehicleTracking(getExternalId());
}
The error occurs when I call commandTrackVehicle() from the vehicle module with mobility->commandTrackVehicle();.
The error text in SUMO is:
error: tcpip::Storage::readIsSafe: want to read 1717063210 byte from Storage, but only 12 remaining
Does anybody has an idea how to solve this problem or to get more information about the error? Thanks.
Your code should work if you change TraCIBuffer() << "View #0" to TraCIBuffer() << std::string("View #0").
The reason is a bit complex:
SUMO's TraCI API defines its data type string as
32 bit string length, followed by text coded as 8 bit ASCII
Veins 3 has an overload for sending std::string as a TraCI-compatible string. It does not have one for a pointer-to-byte(s) data type (char*). That is, if you insert a char* (which is what "View #0" is to the compiler) into a Veins 3 TraCIBuffer, it won't know to apply this special formatting, confusing SUMO by sending a Byte (that it tries to interpret as a 32 bit length, followed by trying to read as many Bytes as the "length" indicates, and failing).
I'm attempting to read a PE file in C.
I have code MZ and then, I don't know to code e_lfanew.
#include <stdio.h>
#include <Windows.h>
int main()
{
errno_t err;
FILE *fp = NULL;
char *buffer;
err = fopen_s(&fp, "D:\\pe.exe", "rb");
printf("----------dos header---------- \n");
buffer = new char[3]; // malloc: cap phat bo nho//
memset(buffer, 0x0, sizeof(char)* 3); // memset: gan gia tri cho buffer//
fread(buffer, 2 * sizeof(char), 1, fp);
printf("e_magic: %s \n", buffer);
}
Also, I am aware this is possible via the Win32 API; however, I want to learn from this and do it myself.
Typically one would define a struct called DOS_Header and read the complete struct from the file. That struct then has a field e_lfanew which can directly be accessed without pointer arithmetics etc.
e_lfanew then points to the PE signature (PE\0\0), followed by the COFF header. Then the story repeats: create a struct called COFF_Header and read the complete struct from the file...
As #thomas weller said you need to typecast your buffer to IMAGE_DOS_HEADER.
The last field tells you where the PE header is, then read that offset and typecast the buffer to IMAGE_NT_HEADER. The other way is to just map the file in and typecast the relevant buffers memory.
To get details about any header information you can directly fill it to the structure for example
IMAGE_DOS_HEADER imgDosHdr = {0};
FILE *fp = fopen("Path_to_Pe","rb");
if(fp == NULL) return;
fseek(fp,0,SEEK_SET);
fread(&imgDosHdr,1,sizeof(IMAGE_DOS_HEADER),fp);
fclose(fp);
Hence you can get all the details of PE file Header by Setting the
fseek.