Should avoid global variable used as "parameter" in a function - c++

I'm thinking about a different implementation of this part of a code:
unsigned int whyamIexisting=100000; // also good for me static unsigned ...
double rand_number_generation(){
// create random number [0,1]
static unsigned int rand_counter=0;
rand_counter++;
if( rand_counter > whyamIexisting) {
update_my_seed(time(NULL));
rand_counter=0;
}
// random number generation
return thats_your_gorgeous_numb(); // random algorithm
}
main(){
...modify whyamIexising
...use rand_number_generation() several times
...
}
Should I not use global variable? And if yes what solution will you suggest?
thanks!

If you are working with multiple functions and using a global variable, i would suggest you not to modify it and instead use local variable for storing it and then do the modification.
I usually avoid using global variables. :-)

There... gone!
double rand_number_generation(unsigned int whyamIexisting){
// create random number [0,1]
static unsigned int rand_counter=0;
rand_counter++;
if( rand_counter > whyamIexisting) {
update_my_seed(time(NULL));
rand_counter=0;
}
// random number generation
return thats_your_gorgeous_numb(); // random algorithm
}
main(){
unsigned int limit = 17;
...use rand_number_generation(limit) several times
...
}
There is no point having a global variable in your case. It only makes the program hard to maintain if it were to grow. It doesn't add anything in the example you have given.

I don't know the rest of code, so it's based on fragments you posted and may be completely wrong.
whyamIexisting is kind of a description for environment where rand_number_generation is run, but it also describes it's state, same as rand_counter.
From tags I see that you write in C++, which is an object oriented language. The thing about object orientation is that you have, you know, objects. Probably not everyone will agree with me (thinking about my High School IT teacher), but I personally consider putting everything that has it's own state into class as a good practise. Does object containing whyamIexisting as it's field, rand_counter as another and rand_number_generation as it's method (and probably getter and setter for whyamIexisting) solve your problem?
Unless you don't use whyamIexisting anywhere else in the code, because then you can simply make it local in main and pass as parameter to function rand_number_generation.

Related

How do you determine the size of a class when reverse engineering?

I've been trying to learn a bit about reverse engineering and how to essentially wrap an existing class (that we do not have the source for, we'll call it PrivateClass) with our own class (we'll call it WrapperClass).
Right now I'm basically calling the constructor of PrivateClass while feeding a pointer to WrapperClass as the this argument...
Doing this populates m_string_address, m_somevalue1, m_somevalue2, and missingBytes with the PrivateClass object data. The dilemma now is that I am noticing issues with the original program (first a crash that was resolved by adding m_u1 and m_u2) and then text not rendering that was fixed by adding mData[2900].
I'm able to deduce that m_u1 and m_u2 hold the size of the string in m_string_address, but I wasn't expecting there to be any other member variables after them (which is why I was surprised with mData[2900] resolving the text rendering problem). 2900 is also just a random large value I threw in.
So my question is how can we determine the real size of a class that we do not have the source for? Is there a tool that will tell you what variables exist in a class and their order (or atleast the correct datatypes or datatype sizes of each variable). I'm assuming this might be possible by processing assembly in an address range into a semi-decompiled state.
class WrapperClass
{
public:
WrapperClass(const wchar_t* original);
private:
uintptr_t m_string_address;
int m_somevalue1;
int m_somevalue2;
char missingBytes[2900];
};
WrapperClass::WrapperClass(const wchar_t* original)
{
typedef void(__thiscall* PrivateClassCtor)(void* pThis, const wchar_t* original);
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
}
So my question is how can we determine the real size of a class that
we do not have the source for?
You have to guess or logically deduce it for yourself. Or just guess. If guessing doesn't work out for you, you'll have to guess again.
Is there a tool that will tell you what variables exist in a class and
their order (or atleast the correct datatypes or datatype sizes of
each variable) I'm assuming by decompiling and processing assembly in
an address range.
No, there is not. The type of meta information that describes a class, it's members, etc. simply isn't written out as the program does not need it nor are there currently no facilities defined in the C++ Standard that would require a compiler to generate that information.
There are exactly zero guarantees that you can reliably 'guess' the size of a class. You can however probably make a reasonable estimate in most cases.
The one thing you can be sure of though: the only problem is when you have too little memory for a class instance. Having too much memory isn't really a problem at all (Which is what adding 2900 extra bytes works).
On the assumption that the code was originally well written (e.g. the developer decided to initialise all the variables nicely), then you may be able to guess the size using something like this:
#define MAGIC 0xCD
// allocate a big buffer
char temp_buffer[8092];
memset(temp_buffer, MAGIC, 8092);
// call ctor
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
// step backwards until we find a byte that isn't 0xCD.
// Might want to change the magic value and run again
// just to be sure (e.g. the original ctor sets the last
// few bytes of the class to 0xCD by coincidence.
//
// Obviously fails if the developer never initialises member vars though!
for(int i = 8091; i >= 0; --i) {
if(temp_buffer[i] != MAGIC) {
printf("class size might be: %d\n", i + 1);
break;
}
}
That's probably a decent guess, however the only way to be 100% sure would be to stick a breakpoint where you call the ctor, switch to assembly view in your debugger of choice, and then step through the assembly line by line to see what the max address being written to is.

Explaining C++ (C Binding Library) Function

I'm trying to understand a Function/Method in a Library in order to port it to Java however some parameters don't make any sense to me and reading the source code the library is based on is not helping.
Function (Note the API has few comments (We can also ignore the calc handle since it's got a supplier method))
Ssr calc_ssr(CalcHandle *calc, NoteInfo *rows, size_t num_rows, float music_rate, float score_goal) {
std::vector<NoteInfo> note_info(rows, rows + num_rows);
auto skillsets = MinaSDCalc(
note_info,
music_rate,
score_goal,
reinterpret_cast<Calc*>(calc)
);
return skillset_vector_to_ssr(skillsets);
}
NoteInfo Struct
struct NoteInfo
{
unsigned int notes;
float rowTime;
};
MinaSDCalc
// Function to generate SSR rating
auto
MinaSDCalc(const std::vector<NoteInfo>& NoteInfo,
const float musicrate,
const float goal,
Calc* calc) -> std::vector<float>
{
if (NoteInfo.size() <= 1) {
return dimples_the_all_zero_output;
}
calc->ssr = true;
calc->debugmode = false;
return calc->CalcMain(NoteInfo, musicrate, min(goal, ssr_goal_cap));
}
Calc expected input file data (Only care about the #Notes: ...)
Pastebin
Question
What is NoteInfo in calc_ssr, I don't know any C or C++ so the *rows to me just seems like a pointer to a Noteinfo instance, however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me (pairing this with the fact that NoteInfo needs another parameter rowTime which I think is time of Note occurrence in the file which means that value must not be constant otherwise the produced result would be inaccurate)
Github Project: https://github.com/kangalioo/minacalc-standalone (The code alone may not explain enough but it's worth a try; best to look at API.h and discern what's used from there. Though I do warn you a lot of the Code is esoteric)
Sorry if this doesn't make much sense but I've been looking into this since June/July and this API is the closest abstraction from the bare C++ code I could find.
NoteInfo * rows here is pass by pointer. So, rows actually is a pointer to an instance of type NoteInfo. This is one of the ways to pass arrays in c++ to a function. Since arrays are contiguous in memory so we can just increment the pointer by one and get the next element of the array.
for example look at these three ways to do exactly one thing, parameter to pass an array to a function :-
1. void myFunction(int *param) {}
2. void myFunction(int param[10]) {}
3. void myFunction(int param[]) {}
Look into this link for more understanding : https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Also search for pass by pointer and pass by reference to look into different ways of passing arguments in c++.
2.however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me: as to this question of yours, you can now see MinaSDCalc is actually getting an array and not a single instance as passing the pointer is also one of the ways of passing an array in c++.

Minimalizing variable's scope in C++

I am programming for a while now and I've started trying to improve my code. Since I really hate creating bazillion of variables that are used only once in long function, is it good practice to shorten variable scope by using brackets?
i.e.
instead writing:
void fcn()
{
int var1;
// some part of fcn
// use of var1;
// rest of fcn
}
write:
void fcn()
{
// some part of fcn
{
int var1;
// use of var100;
}
// rest of fcn
}
Yes it is indeed a good idea to keep the scope of variables as tight as possible.
In your case, unless you are absolutely certain that your code using var1 will only ever be used in fcn (and if my experience is anything to go by, I tend to misjudge that), you could split that code out to a separate function. Your program will scale better that way, and testing will also be simpler. Else, use scope blocks as you currently do.
There are certainly context in which this approach is a good practice.
It is so wide spreaded around 'if/range for/while/case' statements that explicit initializer in those statement were added in C++17 and C++20.
You shouldn't write int var1; anywhere.
Firstly var1 is a terrible name.
Secondly you now have the potential for undefined behaviour, if any code path can read var1 before it is assigned.
Prefer
int meaningfulName = initialValue;
Or even better
const int meaningfulName = value;
Having done that, the scopes you are choosing between are more restricted. If there is still a choice, prefer the narrowest scope possible.

Can we scramble the declaration order in C or C++?

Is there a method/plugin/addon in place to ignore the following clause (for some c/c++ compiler)? To reorder the declaration of members in a struct during the same stage as the preprocessor or similar? Perhaps by adding a keyword like volatile or something similar to the front of the struct declaration.
I was thinking: a compiler option, a built-in keyword, or a programming method.
C99 §6.7.2.1 clause 13 states:
Within a structure object, the
non-bit-field members and the units in
which bit-fields reside have addresses
that increase in the order in which
they are declared.
C++ seems to have a similar clause, and I am interested in that as well. The clauses both specify a reasonable feature to have in terms of later declarations have greater memory offsets. But, I often do not need to know the declaration order of my struct for interface purposes or some other. It would be nice to write some code like:
scrambled struct foo {
int a;
int bar;
};
or, suppose order doesn't really matter with this struct.
scrambled struct foo {
int bar;
int a;
};
And so, have the declaration of a and b swapped randomly each time I compile. I believe that this also applies to setting aside stack memory.
main() {
scrambled int a;
scrambled int foo;
scrambled int bar;
..
Why do I ask?
I was curious to see how program bots were created. I watched some people analyzing memory offsets for changes while running the program to which a hack will be created.
It seems the process is: watch the memory offsets and take note of the purpose for the given offsets. Later, hack programs will inject desired values into memory at those offsets.
Now suppose those memory offsets changed every single time the program is compiled. Maybe it would hinder or dissuade individuals from taking the time to understand something you would rather they not know.
Run-time foxing is the best way, then you only have to release a single version. Where a struct has several fields of the same type, you can use an array instead. Step 1. Instead of a structure with three int fields use an array
#define foo 0
#define bar 1
#define zee 2
struct abc {
int scramble [3];
};
...
value = abc.scramble[bar];
Step 2, now use an indexing array which is randomised every time the program is run.
int abcindex [3]; // index lookup
int abcpool [3]; // index pool for randomise
for (i=0; i<3; i++) // initialise index pool
abcpool[i] = i;
srand (time(NULL));
for (i=0; i<3; i++) { // initialise lookup array
j = rand()%(3-i);
abcindex[i] = abcpool[j]; // allocate random index from pool
abcpool[j] = abcpool[2-i]; // remove index from pool
}
value = abc.scramble[abcindex[bar]];
Another way to try to fox a hacker is to include subterfuge variables that behave as if they have something to do with it but make the program exit if tampered with. Lastly you can keep some kind of checksum or encrypted copy of key variables, to check if they have been tampered with.
Your intention is good, but the solution isn't (sorry). Usually you can't recompile your program before each run. The attacker will hack the inspected program. However, there's a solution, called ASLR. The operating system could change the load address for you, thus making "return oriented programming" and "return to libc like hacks harder".

good practice - similarly named variables

Trivial issue, but comes up a lot for me, and I imagine others too. Does anybody have a really good, really clever solution?
void some_function (obj &A, obj &B)
{
// do stuff with A...
//e.g.
double number_A = (value - A.member_func() ) * A.other_func();
// do stuff with B. similar BUT NOT EXACTLY like A...
//e.g.
double number_B = (value + B.member_func() ) * A.other_func();
// !!!!
// Big time TYPO - should say "B.other_func()", not "A.other_func()" !!!!
// !!!!
}
Any good guards against these types of errors?
I often have to work on two analogous variables, say one named version "A" and the other "B".
Because the code for each one is similar, I often use the code that worked on "A" as a "template" (i.e. copy & paste) for the code that works on "B" - making the small adjustments so that the code becomes appropriate for B.
Becuase I am human, I sometimes forget to change "A" to "B" in certain locations when copying the code. If I am lucky, this will cause the program to crash. Either way, this is disastrous.
Does anybody know any clever tricks for preventing such typos?
I've thought of...
enclosing brackets { } to try to restrict the scope of variables - but if objects A and B are in the function arguments, then this doesn't solve it.
dividing every function into sub-functions - one for A and one for B. This is a bit cumbersome from the developer perspective (passing/returning many of variables).
work only with pointers to the objects themselves - not the actual objects. This way we can { scope-control } the pointers. Also cumbersome, (and the overhead for defining a pointer is negligible, even if I call the function very, very often, right?)
In the example you give, the best defence is to do as little as possible in each function:
void some_function (obj &A, obj &B)
{
double number_A = do_stuff(A);
double number_B = do_similar_stuff(B);
}
double do_stuff(obj &A) {
return (value - A.member_func() ) * A.other_func();
}
// EITHER
double do_similar_stuff(obj &A) {
// no variable rename when copying == no problem
return value + A.member_func() ) * A.other_func();
}
// OR
double do_similar_stuff(obj &B) {
// A not in scope == very brief problem until compiler tells us
return value + B.member_func() ) * A.other_func();
// Beware, also, the nightmare scenario that there's some *other*
// `A` in scope, so this *still* compiles. For that reason, prefer
// the other option unless there's some good reason why this parameter
// should be `B`, and don't name member function parameters the same
// as data members etc.
}
Alternatively, you could make the relation between the two kinds of "stuff" explicit. Assuming that the unmatched parenthesis in your B code is supposed to go in the same place as the A. It all depends whether there really is a logical relationship between the two similar-looking operations:
void some_function (obj &A, obj &B)
{
double number_A = do_stuff(A, true);
double number_B = do_stuff(B, false);
}
double do_stuff(obj &A, bool subtract) {
// yeah, never call variables "tmp". Unless you have no context
// to give them meaning.
// Depending on the type of `tmp`, there might be a better way to
// write this, using multiplication by -1. But let's not assume, we'll do
// one refactor at a time.
auto tmp = subtract ? value - A.member_func() : value + A.member_func();
return tmp * A.other_func();
}
Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.
It may also mean you can test that your formula with A is correct independently of whether your formula with B is correct, and sundry other benefits of short functions.
I have a few ideas in mind
you could use snippets if your editor supports them or move to an editor/ide which has support for them (personally I use kdevelop and snippets are very useful as they replace all occurences of a snippet variable)
you could also use refactoring (in a separate function if you
already used the names this one)
also selecting a piece of code and doing replace all in selection
might help
using defines is also an option
Still, going with a smarter IDE is the best in my opinion.
I think your best bet is not have similar function names in other classes. Also, having unit tests coupled with peer code reviews should catch these errors most of the time. However, there have been many times in SW history where these types of errors are never caught until many days, months, or years later.