-
I need to parse a binary format which contains serialized lists of class objects. A given class object could be present in several lists and all those lists are serialized, but the serializer does not emit a class object more than once. When a class object is emitted it gets a unique id and if the same class object is found again only it's unique id gets emitted by the serializer instead of the complete object.
Each class object that is not emitted yet by the serializer gets a unique id which is emitted before the class object itself. This way it is guaranteed that unique ids are monotonically incrementing in the binary file. But this also means that the format parser needs to keep track of what is the highest unique id which was already read so that if a lower or equal unique id is found the parser knows that it will only find the id not the object. To make things worse, the number of objects in a list is also dynamic. To make it even worse, the number of lists is also dynamic. Both counts are specified in the binary file though. As far as I can tell I would need something comparable to the following hypothetical pattern language code snippet:
Something comparable is implemented by the Wireshark Generic Dissector language wsgd var command section Thanks in advance for any help. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Hi! The pattern language does have support for global variables. The only problem your code seems to have is that you're trying to set the global variable inside the struct. To do this, you have to define a function that does it and call that function from inside the struct. Example: u8 lastValue;
fn setLastValue(u8 value) {
lastValue = value;
};
struct Test {
u8 value;
setLastValue(value);
};
Test test[10] @ 0x00; Hope that helps |
Beta Was this translation helpful? Give feedback.
-
Thanks @WerWolv , the example helped a lot. But something seems to be odd. I tried to create a minimal example. OS Win10 x64, little endian. ImHex v1.12.1. The binary file is just a vector of u16 indices, starting from 1, and one additional byte after each index.
The code contains everything that is needed except the actual variable placement which is found within test cases found further below.
Test 1 works as I imagine it should. Console output shows that the function executes exactly once and the matched pattern is correct. I do not know why std::print prefixes every console output line with "[i] ", but it does.
Test 2 changes the variable to an array with 1 element. According to the console output the function is executed twice for some reason which is unexpected. The first run does not seem to emit anything to the resulting matched pattern. The second execution finds that the object id is already emitted so the additional byte after the object index is skipped (the function returns false). I do not understand why the function executes twice.
Test 3 changes the variable to an array with more than 1 elements. This result indicates that the function only executes twice for the first element. For every additional array elements the function only executes once. The results back up the previous assumptions.
Why could it be that the function executes one additional unexpected time when the variable is an array? The behavior does not change if the variable is a member of a struct or multiple structs. |
Beta Was this translation helpful? Give feedback.
-
Hello @WerWolv, as the format I have to support guarantees that the object indices monotonically increment the additional unexpected call does not cause any issues as long as I test for |
Beta Was this translation helpful? Give feedback.
Hi! The pattern language does have support for global variables. The only problem your code seems to have is that you're trying to set the global variable inside the struct. To do this, you have to define a function that does it and call that function from inside the struct.
Example:
Hope that helps