Sign in to follow this  
Ntvu

Reverse Engineering ...?

Recommended Posts

Ntvu    100
Say I have a simple program written in C++:
#include <iostream> 
using std::cout; 

int main()
{
    int value = 5;
    while (true) cout << value << endl;

    return 0; 
}
Would there be any possible way to alter the value of value? I heard that it involved using a disassembler or some other related tool, but I'm not quite sure yet. But I heard on several websites that if you were to change the values of a program, you could either disassemble it and somehow put it back together again, or you could use a program such as Tsearch or OllyDbg to change the values. Also, if this is possible, say I have this improved code:
#include <iostream>
using std::cout; 
function encrypt(int val) { return (val + 5) * 8; }
function decrypt(int val) { return (val / 8) - 5; }

int main()
{
    int value = encrypt(5); 
    while (true) cout << decrypt(value) << endl;

    return 0; 
}
Would this make it harder to change the values? This is something that I've been wondering about for a quite a while. There's a lot of things that I've heard on other sites, but I wanted to know how one goes about doing this, and how you can prevent this from happening. Edit: By the way, how do I insert C++ code tags?

Share this post


Link to post
Share on other sites
Ravyne    14300
Whether the second code is harder depends on whether the functions encrypt / decrypt are inlined and collapsed. Simple statements like those will likely be entirely evaluated at compile time, and the result stored in the application in plain sight. Thus, it wouldn't become any harder to find, you'd just need to know the altered value you are looking for. Of course, I suppose you have to know the algorithm to make any meaningful change to the value but something so easy as in your example is not difficult to reverse engineer, its high-school algebra (or which you might plainly see due to it *not* being inlined elsewhere). If the function is not inlined/collapsed, then you still have the original value in plain sight and easily alterable; no change in difficulty.

Share this post


Link to post
Share on other sites
brandonman    102
I think he is talking more about modifying the content of a program in runtime, when the program has no input already coded in, like a cin. I just want to ask the OP, are you wanting to change a program and THEN run it with a new value, or are you wanting to change this value "On the Fly" while it is running? With the reverse engineering title, I would assume the latter. I will check online and see what I can find. Also, use [ source ] and [ /source ] for code tags, but ommit the spaces.

Edit: After some googling, here is an article I came up with on Code Injection. I don't think this is runtime, but interesting none the less. Here

Share this post


Link to post
Share on other sites
F1N1TY    478
No, both methods of code are easy to disassemble, esp. with programs that monitor memory changes in order to find addresses of values, then alter those values themselves.

As programs get larger, however, there might be thousands of cases where a value == 5 (within a loop, elements in a string, etc) which would make that exact number harder to pin-point.

Honestly, you shouldn't bother trying to make this program hacker-proof, because you'll just give yourself a headache. Single player games, shouldn't really be of concern to you (since who really cares, if some bored hacker gives himself unlimited guys in single player). Multiplayer differences can be caught (by comparing the values against a known good value, etc) and taken care of (usually by exiting with an error).

Share this post


Link to post
Share on other sites
Drigovas    509
It is straight out not possible to protect yourself in this fashion. All you would be doing by inserting a 'decrypt/encrypt' pair [assuming it isn't inlined, as was already pointed out] would be imposing constraints on what step in your program a certain variable is vulnerable to attack. All the attacker has to do is change it before it gets encrypted, or after it gets decrypted. That is assuming that your attacker can't discover your encryption system [which they can always do]. It gets even easier if they can discover your encryption system [which is always the case], since they can just assign 'encrypt(X)' where ever they want X to be later decrypted [or even scramble your encrypt/decrypt functions to make them do nothing at all, thus making this a moot point]

Pay close attention, because this is going to save you a lot of worry and a lot of time. You CAN NOT guarantee the integrity of your program or your data when your attacker has absolute control over the environment on which you are running your program [which is the case any time you are letting someone else run your code on their machine]. It can't be done. I am only being this explicit and blunt in this because this issue seems to come up quite often, and the resolution is always the same. It is wasted effort.

Share this post


Link to post
Share on other sites
Antheus    2409
Quote:
Original post by Ntvu
Say I have a simple program written in C++:


First example compiles into:
00401000  mov         eax,dword ptr [__imp_std::endl (402038h)] 
00401005 mov ecx,dword ptr [__imp_std::cout (402044h)]
0040100B push eax
0040100C push 5
0040100E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]
00401014 mov ecx,eax
00401016 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40203Ch)]
0040101C jmp main (401000h)


It doesn't take an assembly expert to see that push 5 is where the value is passed.

But since applications today are typically compiled (as opposed to written in assembly), some patterns emerge.

For example, the double push + call is a function call. These kinds of patterns can somewhat trivially found in code, and then it's just a matter of backtracking to where values are manipulated.

Most attempts of code protection focus on two areas. One is to obscure the code in a way that makes identification of such patterns difficult. The other is to obstruct disassemblers. Either prevent debuggers from running or attempt to hide the code from them.

At the end of the day, CPU needs plain old code to do what it needs to do. As long as that exists, there is no way to stop the attackers. This is identical to analog hole.

The only effective way is to prevent the problem from happening in the first place - by not giving access to code by running it on server. Of course, a whole different set of attack vectors exists for those.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this