Related
As you might know DDD literature suggests that we should treat " numeric quantativies with some unit " as value objects, not as primitive types ( ints, bigdecimal ). Some examples of such value objects are money, distance or file size. I agree with the big picture
However there is something I cannot understand. Namely conversion errors when representating something in one unit, converting it to other unit and back. This process might lose some information. Take for example file size. Lets say I have file whose size is 3.67 MB and I convert that to other instance of FileSize whose unit would be GB by dividing 3.67 with 1024. Now I have FileSize of ( approximately ) 0.00358398437 GB. If I now try to convert it back to MB the result is not 3.67 MB. If however I dont use value object but instead only use primitive information " sizeInBytes " ( long ) I cannot lose information on conversion errors.
I must have missed something. Is my example just plain stupid? Or is it acceptable to lose some info when converting from one unit to another? Or should FileSize always carry also excat file size in bytes ( with approx.size in given unit )?
Thanks in advance!
What you are describing is more an implementation problem of your concrete example than a problem with the approach. The idea of using value objects to represent amounts with a unit is to avoid mistakes like adding Liters to Kilometers or doing 10cm + 10Km = 20cm. Value objects, when developed correctly, will enforce that the operations are done correctly between different units.
Now, how you implement these value objects with your programming language, is a different problem. But for your concrete example, I would say that the value object will internally have a long field with the size in Bytes, no matter what unit you use to initialize the object. In this case, the unit will be used to convert the initialization value to the right amount of bytes and also for display purposes, but when you have to add 2 FileSizes, you can add the internal amounts in bytes.
we should treat " numeric quantativies with some unit " as value objects, not as primitive types ( ints, bigdecimal ).
Yes, that's right. More generally, we're encouraged to encapsulate data structures (an integer alone is a trivially simple data structure) behind domain specific abstractions. This is one good way to leverage type checking - it gives the checker the hints that it needs to detect a category of dumb mistakes.
Namely conversion errors when representating something in one unit, converting it to other unit and back. This process might lose some information.
That's right. More generally: rounding loses information.
I dont use value object but instead only use primitive information " sizeInBytes " ( long ) I cannot lose information on conversion errors.
So look carefully at that: if you perform the same sequence of conversions you described using primitive data structures, you would end up with the same rounding error (after all, that's where the rounding error came from: the abstraction of the measurement defers the calculation to its internal general purpose representation).
The thing that saves you from the error is not discarding the original exact answer.
What domain modeling is telling you to do is make explicit which values are "exact" and which have "rounding errors".
(Note that in some domains, they aren't even "errors"; many domains have explicit rules about how rounding is supposed to happen. Sadly, they are rarely the rounding rules defined by IEEE-754, so you can't just lean on the general purpose floating point type.)
DDD will also encourage you to track precisely which values are for display/reporting, and which are to be used in later calculations.
Reading this, I think you're misunderstanding what DDD is. The first D is DDD, stands for Domain - aka Domain is a sphere of knowledge. The way you represent a sphere of knowledge aka a Domain - is entirely based on the business domain you're attempting to represent, and will be different based on the business domain.
So...
Domain A: Business User that has X amount of storage space
I upload X file
file X uses 3.67 MB
You have used 1% of your allocated space.
You have 97 MB space remaining
Domain B: Sys Admin - total space is Y amount of storage space
Users have uploaded 3.67 MB
That user has used 1% of their space
That user has 97 MB space remaining
There is 1000 GB total space remaining to allocate to all users / total space remaining.
aka. Sys Admin has one domain - total disk; User has allocated space (sub-set) - they have different domains of knowledge - space.
Also note... DDD is really about sectioning of a domain or sphere of knowledge to the specific users of sub-sections of a system - and not the facts of a system. aka Facts are different from knowledge.
I hope this makes some sense!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
So I'm trying to create an aimbot for a game but I'm having some trouble here, how can I find the player base? If I find the player base then I can get all the information needed such as X, Y positions, current money, ammo, health, armor etc... I'm using CheatEngine 6.4 for this.
The term "PlayerBase" refers to the dynamic address of the player object. Variables like health, armor etc... will typically be member variables of the player class. Variables such as ammo can also be member variables of the weapon class, so not all offsets will be relative to the address of the player object. But you will often seen pointers in the player object that point to the current weapon object.
When the game is created the compiler creates instructions to access the variables by address and relative offset using the class that's been defined. Your goal is to replicate the game logic in accessing these variables.
To find a variable that you assume is a member of the player class, scan for it in cheat engine, then use "Find What Accesses" on the address of the variable. This lists all instructions that access that variable. Hopefully you will see something like "mov eax [ebx+14c]". In this case the address held in ebx is the address of the player object and 0x14c is the offset to the health variable. This is typically a dynamic address, which will be different each time you run the game. Next you would want to find a pointer to this address that you can use that will always point to the correct address. To do this you would trace backwards in the code and hopefully see where ebx gets it's value either inside the current function or in a previous function in the call stack. You will either find a static address which is a global variable or an address that is relative to the base address of a module(such as a DLL or exe) which you can calculate at runtime.
I typically do the same thing in every game and dumb this down to:
Find a good health pointer and remove the last offset. This is a pointer to the "playerbase"
Find Y axis, search unknown initial value, float type. Walk up ladder, and search for increased value. Walk down and decreased value, and keep doing this until you find your Y address. Right Click and press " Memory View for this value". Disect new data structure. Now you should have structure, there you have an array of memory addresses, type the Y address - 8, now you should get all XYZ, and the addresses, type the x address that is on top now, and "-" 4. The address on top is now your PlayerBase. When you need XYZ now, you take "PlayerBase + XOffset", X will be 4 bytes infront of Base, since you took X - 4. and Z will be 4 bytes infront of X, so PlayerBase + 8, and Y will be "+" 0x0C. Cheat Engine shows you the offset behind the address.
I am using this function to copy some structures to the kernel.
But, the problem is that I have to copy three data structures which are part of a bigger data structure. NOTE: the 3 data structures are contiguous in the bigger data structure.
SO, In my copy user function I pass the pointer of the 1st data structure and give the length of all the 3 data structure. But, when I go to user-space and print the 1st element of the 2nd data structure it gives some other value.
SO, what am I doing wrong.
As, a solution I made 3 copt_to_user calls and to my surprise it works fine. Its the problem when I make a single copy_to_user call.
Please, let me know what could be the reason.
Hey guys thanks for the answer it was a alignment issue , but, going further, if I want to pad an internal structure how do I do it..?
Example-
structure d{
struct b;
struct c; //I want to make this structure a padded one, how to go about it?
struct d;
}
As mentioned in the comments, this really seems to be an alignment problem. Gcc will probably add some padding between the structures a, b and c in struct d. Depending on how you instantiated the one in userland, it could be a problem. You can force gcc to not generate padding, using __atribute__ ((packed)) on your structure, but unless this structure maps to hardware registers, it's usually a bad idea as it will lead to worse performance when accessing fields of that structure.
Another possible problem would be if your kernel is 64 bits and your userland program is 32 bits, in this case you need to use fixed size types to be sure to have the same layout.
Does anyone have a detailed explanation on how integers can be exploited? I have been reading a lot about the concept, and I understand what an it is, and I understand buffer overflows, but I dont understand how one could modify memory reliably, or in a way to modify application flow, by making an integer larger than its defined memory....
It is definitely exploitable, but depends on the situation of course.
Old versions ssh had an integer overflow which could be exploited remotely. The exploit caused the ssh daemon to create a hashtable of size zero and overwrite memory when it tried to store some values in there.
More details on the ssh integer overflow: http://www.kb.cert.org/vuls/id/945216
More details on integer overflow: http://projects.webappsec.org/w/page/13246946/Integer%20Overflows
I used APL/370 in the late 60s on an IBM 360/40. APL is language in which essentially everything thing is a multidimensional array, and there are amazing operators for manipulating arrays, including reshaping from N dimensions to M dimensions, etc.
Unsurprisingly, an array of N dimensions had index bounds of 1..k with a different positive k for each axis.. and k was legally always less than 2^31 (positive values in a 32 bit signed machine word). Now, an array of N dimensions has an location assigned in memory. Attempts to access an array slot using an index too large for an axis is checked against the array upper bound by APL. And of course this applied for an array of N dimensions where N == 1.
APL didn't check if you did something incredibly stupid with RHO (array reshape) operator. APL only allowed a maximum of 64 dimensions. So, you could make an array of 1-64 dimension, and APL would do it if the array dimensions were all less than 2^31. Or, you could try to make an array of 65 dimensions. In this case, APL goofed, and surprisingly gave back a 64 dimension array, but failed to check the axis sizes.
(This is in effect where the "integer overflow occurred"). This meant you could create an array with axis sizes of 2^31 or more... but being interpreted as signed integers, they were treated as negative numbers.
The right RHO operator incantation applied to such an array to could reduce the dimensionaly to 1, with an an upper bound of, get this, "-1". Call this matrix a "wormhole" (you'll see why in moment). Such an wormhole array has
a place in memory, just like any other array. But all array accesses are checked against the upper bound... but the array bound check turned out to be done by an unsigned compare by APL. So, you can access WORMHOLE[1], WORMHOLE[2], ... WORMHOLE[2^32-2] without objection. In effect, you can access the entire machine's memory.
APL also had an array assignment operation, in which you could fill an array with a value.
WORMHOLE[]<-0 thus zeroed all of memory.
I only did this once, as it erased the memory containing my APL workspace, the APL interpreter, and obvious the critical part of APL that enabled timesharing (in those days it wasn't protected from users)... the terminal room
went from its normal state of mechanically very noisy (we had 2741 Selectric APL terminals) to dead silent in about 2 seconds.
Through the glass into the computer room I could see the operator look up startled at the lights on the 370 as they all went out. Lots of runnning around ensued.
While it was funny at the time, I kept my mouth shut.
With some care, one could obviously have tampered with the OS in arbitrary ways.
It depends on how the variable is used. If you never make any security decisions based on integers you have added with input integers (where an adversary could provoke an overflow), then I can't think of how you would get in trouble (but this kind of stuff can be subtle).
Then again, I have seen plenty of code like this that doesn't validate user input (although this example is contrived):
int pricePerWidgetInCents = 3199;
int numberOfWidgetsToBuy = int.Parse(/* some user input string */);
int totalCostOfWidgetsSoldInCents = pricePerWidgetInCents * numberOfWidgetsToBuy; // KA-BOOM!
// potentially much later
int orderSubtotal = whatever + totalCostOfWidgetInCents;
Everything is hunky-dory until the day you sell 671,299 widgets for -$21,474,817.95. Boss might be upset.
A common case would be code that prevents against buffer overflow by asking for the number of inputs that will be provided, and then trying to enforce that limit. Consider a situation where I claim to be providing 2^30+10 integers. The receiving system allocates a buffer of 4*(2^30+10)=40 bytes (!). Since the memory allocation succeeded, I'm allowed to continue. The input buffer check won't stop me when I send my 11th input, since 11 < 2^30+10. Yet I will overflow the actually allocated buffer.
I just wanted to sum up everything I have found out about my original question.
The reason things were confusing to me was because I know how buffer overflows work, and can understand how you can easily exploit that. An integer overflow is a different case - you cant exploit the integer overflow to add arbitrary code, and force a change in the flow of an application.
However, it is possible to overflow an integer, which is used - for example - to index an array to access arbitrary parts of memory. From here, it could be possible to use that mis-indexed array to override memory and cause the execution of an application to alter to your malicious intent.
Hope this helps.
This question already has answers here:
Closed 14 years ago.
See: Understanding Pointers
In many C flavoured languages, and some older languages like Fortran, one can use Pointers.
As someone who has only really programmed in basic, javascript, and actionscript, can you explain to me what a Pointer is, and what it is most useful for?
Thanks!
This wikipedia article will give you detailed information on what a pointer is:
In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address. Obtaining or requesting the value to which a pointer refers is called dereferencing the pointer. A pointer is a simple implementation of the general reference data type (although it is quite different from the facility referred to as a reference in C++). Pointers to data improve performance for repetitive operations such as traversing string and tree structures, and pointers to functions are used for binding methods in Object-oriented programming and run-time linking to dynamic link libraries (DLLs).
A pointer is a variable that contains the address of another variable. This allows you to reference another variable indirectly. For example, in C:
// x is an integer variable
int x = 5;
// xpointer is a variable that references (points to) integer variables
int *xpointer;
// We store the address (& operator) of x into xpointer.
xpointer = &x;
// We use the dereferencing operator (*) to say that we want to work with
// the variable that xpointer references
*xpointer = 7;
if (5 == x) {
// Not true
} else if (7 == x) {
// True since we used xpointer to modify x
}
Pointers are not as hard as they sound. As others have said already, they are variables that hold the address of some other variable. Suppose I wanted to give you directions to my house. I wouldn't give you a picture of my house, or a scale model of my house; I'd just give you the address. You could infer whatever you needed from that.
In the same way, a lot of languages make the distinction between passing by value and passing by reference. Essentially it means will i pass an entire object around every time I need to refer to it? Or, will I just give out it's address so that others can infer what they need?
Most modern languages hide this complexity by figuring out when pointers are useful and optimizing that for you. However, if you know what you're doing, manual pointer management can still be useful in some situations.
There have been several discussions in SO about this topic. You can find information about the topic with the links below. There are several other relevant SO discussions on the subject, but I think that these were the most relevant. Search for 'pointers [C++]' in the search window (or 'pointers [c]') and you will get more information as well.
In C++ I Cannot Grasp Pointers and Classes
What is the difference between modern ‘References’ and traditional ‘Pointers’?
As someone already mention, a pointer is a variable that contains the address of another variable.
It's mostly used when creating new objects (in run-time).