Format string for printf hacking - c++

This is hacking for a useful (non-malicious) purpose and I'm not sure what I want can be done but I'd like to try. I'm running software that is closed source so I can't modify the original function call. The call is:
sprintf(string, this->LabelFormat, value)
And this->LabelFormat is %-#6.3g by default. The purpose is to format labels for a legend of doubles, so value is a number.
I can set this->LabelFormat to whatever I want. I would like to perform a mapping from numbers to strings, for example:
value | string
--------------
0.0 | None
1.0 | I
2.0 | J
3.0 | K
and so on. Is it at all possible to manipulate the format string to perform a specified mapping for me since I cannot modify the original code?

What you are looking for is possible with API Hooking
API hooking consists of intercepting a function call in a program and redirecting it to another function. By doing this, the parameters can be modified, the original program can be tricked if you choose to return an error code when really it should be successful, and so on. All of this is done before the real function is called, and in the end, after modifying/storing/extending the original function/parameters, control is handed back over to the original function until it is called again.
You would have to intercept the original call to the function with the sprintf and overwrite the this->LabelFormat with the desired value before handing over control to the function.
For further information, go to Detours - Microsoft Research

I think it is not possible with format string only. You should add extra machine instructions somewhere. For example, you can replace sprintf function with your own.

If you have access to value before setting LabelFormat then all you have to do is set LabelFormat to the string you want to be displayed (without any % codes in it at all). The function will then ignore the extra parameter but it will have printed what you wanted. If you don't also have aaccess to value then I don't see any way to do the mapping with only format codes.

Related

Extracting number of bits in a macroblock from VVC VTM reference software

Final:Result after calculating and displaying the differenceI am new to VVC and I am going through the reference software's code trying to understand it. I have encoded and decoded videos using the reference software. I want to extract the bitstream from it, I want to know the number of bits there are in each macroblock. I am not sure which class I should be working with, for now I am looking at, mv.cpp, QuantRDOQ.cpp, and TrQuant.cpp.
I am afraid to mess the code up completely, I don't know where to add what lines of code. Start: Result after calculating and displaying the difference
P.S. The linked pictures are after my problem has been solved, I attached these pictures because of my query in the comments.
As the error says, getNumBins() is not supported by the CABAC estimator. So you should make sure you call it "only" during the encoding, and not during the RDO.
This should do the job:
if (isEncoding())
before = m_BinEncoder.getNumBins()
coding_unit( cu, partitioner, cuCtx );
if (isEncoding())
{
after = m_BinEncoder.getNumBins();
diff = after - before;
}
The simpleset solution that I'm aware of is at the encoder side.
The trick is to compute the difference in the number of written bits "before" and "after" encoding a Coding Unit (CU) (aka macroblock). This stuff happens in the CABACWriter.cpp file.
You should go to to coding_tree() function, where coding_unit() function is called, which is responsible for context-coding all syntax elementes in the current CU.
There, you may call the function getNumBins() twice: once before and once after coding_unit(). The difference of the two value should do the job for you.

Programmatic access to old and new values of a watchpoint in gdb

What I'm really doing is trying to set a watchpoint on the setting or clearing of a single bit. I do that by setting a watchpoint on the word containing the bit, then making it conditional on *word & mask (for setting, or (~*word) & mask for clearing.)
The problem is that some other bit in the same word may be modified, and the condition may happen to already match. If I had the old and new values, I could set a condition of (($old ^ $new) & mask).
I looked at the python gdb.Breakpoint class, but it doesn't seem to receive this information either.
I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.
There's no direct way to get these values in gdb; it's been a wish-list bug (with your exact case as the example...) for years.. The information is stored in the old_val field of the struct bpstats object associated with the breakpoint; but this is only used to print the old value and not exposed elsewhere.
One option might be to change gdb to expose this value via a convenience variable or via Python.
I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.
This seems doable. Your script could check the current execution direction. The main difficulty is remembering to reset the saved value when making this watchpoint, or after disabling and then re-enabling it.

How do I set an Excel RangePtr's Value = Value in C++? Currently I get HRESULT 0x80004005

I have an Excel RangePtr object, and I'm trying to convert its corresponding cells to values instead of formulas. I'm used to doing this in VBA where you can do this simply using r.Value = r.Value. In C++ I've tried an analogous approach:
rng->Value = rng->Value;
But when I run that, I get an exception from the HRESULT 0x8004005. There's nothing within the cell values that should cause Excel to choke; the values being returned ought to be just a _variant_t containing a SAFEARRAY of double values. So what am I doing wrong?
D'oh. Looks like RangePtr.Value actually has to specify a XlRangeValueDataType constant, which isn't present in VBA:
rng->Value[Excel::XlRangeValueDataType::xlRangeValueDefault] = rng->Value;
Or I could have used the Value2 property instead of plain Value:
rng->Value2 = rng->Value2;
Hopefully this will be helpful to someone else who has this problem in the future.
After painful search I came to the same conclusion, and use
value[Excel::XlRangeValueDataType::xlRangeValueDefault] to get the equivalent of range.value in c# or vb in C++/CLI. Let me see if that works... Yes, that's the solution, it works!
Btw: if you ever need to use the Range::Address property you can use the style
Address[false, false, Excel::XlReferenceStyle::xlA1, Type::Missing, Type::Missing]; with the appropriate parameters, of course.
Furthermore, regarding the value property, I found out that the presence of a cell value can be checked by:
Value[Excel::XlRangeValueDataType::xlRangeValueDefault] != nullptr
Frequently, typecasts a la "safe_cast<Excel::Range^>" and "safe_cast<Excel::Workbook^>" are also helpful. The whole subject matter of using Excel automation with C++/CLI is poorly documented.

Quick code advice for beginner

I am a beginner and I want to know whats wrong with this code. I want to count the number of times the push button is being pushed in portA. Then show this values using the LEDS in portC. Thanks
You need braces around a multi-statement block, if you want to use it as the body of an if (or for or whatever) statement:
else if (PORTA.RA2==1) {
count = count+1;
PORTC = count;
}
otherwise only the first statement is conditional; so your code executes PORTC = count; every time, whatever the result of the if tests.
I like to put braces around all such blocks, even there's only a single statement, so I can't forget to add them if I add more statements later.
Also, main must return int not void, and you should take more care formatting your code to match its logical structure.
UPDATE: Also, you never initialise count, so it has an arbitrary floating-point value. You want a small integer type, since it's only supposed to take integer values from 0 to 16, and you need to initialise it:
char count = 0;
If you're setting TRISA to 1 that means the only input on that port is RA0, but you are trying to use RA2. Be sure to clear the ANSELA0 bit. Make sure you set the config bits properly or else your code might not run.
To avoid getting downvoted in the future:
Choose an informative question title.
Properly indent your code.
Say the exact PIC you are using and what board it is on.
Say what development environment and compiler you are using.
Provide pictures of your setup so we can check your wiring.
Most importantly, tell us exactly how you are testing the code, what the expected result is, and what you are actually observing.
My company offers more advice here: http://www.pololu.com/support

understanding print option in rrdtool

Instead of creating a graph, I need to simply output a number that is the average, max or min of some date range supplied. I have had good success with the following code:
rrdtool graph a.png --start=1325484000 --end=1364472365 DEF:power=/data1/bpoll/rrd/ws3/pdu/pdu316/a.rrd:ct12:AVERAGE 'PRINT:power:AVERAGE:%2.1lf'
However, looking at the docu, it says specifying the CF (in this case AVERAGE) is deprecated. Yet I am completely lost as to the new format. At least I can't seem to wrap my head around it. If I leave out the CF, it errors. Where exactly am I going wrong here?
PRINT:power:AVERAGE:%2.1lf
This is the 'old style' syntax, where you pass a dataset and the consolodation function to the PRINT directive.
With the new format, you use a VDEF and so do not need a function as a VDEF is single-valued. However, you need to define the VDEF beforehand.
This is the new format:
VDEF:avgpower:power,AVERAGE
PRINT:avgpower:%2.1lf
In this example, we define a new VDEF value avgpower and print that. It has the same effect as the previous old syntax code, but is in the new sytax, which allows us to also add modifiers to the PRINT statement such as :strftime to print the point in time of maxima, and so on.