Link to home
Start Free TrialLog in
Avatar of cgallagher
cgallagher

asked on

Ensuring a function doesn't change.

I have a problem as follows. We have a piece of software that is written for an MSDos platform and has one VERY important function in it. We need to perform security checks on the executable file to ensure this function hasn't changed. I have already written code to allow me to isolate the function position within the actual exe file on the hard drive. This means I can open an exe file in hex mode search for the start and end of the function and export it to a file on its own. (I this managed with help from SteveGTR here in Experts Exchange)

The way I do this is by inserting assembly before and after the function and then searching for specific text in the exe file. An example of function marking is as follows:


#pragma optimize("", off)

void Test()
{
 // Begin tag
 __asm
   {
     jmp RoutineStart
     mov al,'*'
     mov ah,'*'
     mov al,'*'
     mov ah,'S'
     mov al,'T'
     mov ah,'A'
     mov al,'R'
     mov ah,'T'
     mov al,'*'
     mov ah,'*'
     mov al,'*'
RoutineStart:
   }

 // Your code
 printf("Test test\n");

 __asm
   {
     jmp RoutineEnd
     mov al,'*'
     mov ah,'*'
     mov al,'*'
     mov ah,'E'
     mov al,'N'
     mov ah,'D'
     mov al,'*'
     mov ah,'*'
     mov al,'*'
RoutineEnd:
   }
}

#pragma optimize("", on)


The above ultimately allows me to search for the following hex codes in an executable:

If program was written using Microsoft Visual C++ 6:
EB 16 B0 2A B4 2A B0 2A B4 53 B0 54 B4 41 B0 52 B4 54 B0 2A B4 2A B0 2A

If program was written using Microsoft Visual C++ 1.52:
E9 16 00 B0 2A B4 2A B0 2A B4 53 B0 54 B4 41 B0 52 B4 54 B0 2A B4 2A B0 2A

You can search for these codes by opening an exe file in hex mode using Microsoft Visual C++ 6.

The next step we take is performing a CRC check on the file the function is exported to. This is all working fine apart from the following. If I change a piece of code OUTSIDE of my function, some of the codes BETWEEN the two mentioned markers will change (in the above sample the codes for the 'printf("Test test\n");' will change. As an example I composed the following two 'main' functions:

// VERSION 1
void main(void)
{
     Test();
     printf("finished");
}

// VERSION 2
void main(void)
{
     printf("STARTING");
     Test();
     printf("finished");
}


By using these two differences the codes between the assembly markers changed from:

68 B4 02 9A B2 06 00 00 83 C4 02

to:

68 C8 02 9A B2 06 00 00 83 C4 02


This means that the CRC value now has changed!!! So if we change some other piece of code within the software that has NOTHING to do with this 'very important function', we have to issue a new CRC every time. This we cannot do for legal reasons. If we keep issuing new CRC's then we cannot say the function has DEFINITELY NOT changed...

My question is as follows:

Is there any way that you can say "THIS FUNCTION MUST BE COMPILED/LINKED INTO THE SAME CODES EVERY TIME"?

I hope my question is clear!
Any help is highly appreciated.

Regards,
C.

ASKER CERTIFIED SOLUTION
Avatar of pjknibbs
pjknibbs

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cgallagher
cgallagher

ASKER

Ok, the issue with the hacker is not really an issue in our case. It's not the actual reason we are trying to secure the system. It's a little hard to explain so I won't clutter you with uninteresting details.

You were right about the static string issue within the printf function, but it seems that it is a little more complicated than that alone. Removing all the statics etc from a function that is excessively larger does not erradicate the problem, but it does help a small bit. The code still seems to change when another area is modified. It would take too long to figure out the lines that are causing the problem because of the size of the code I'm trying to secure so I'm not going to bother. I'm going to have to find another way to check whether a function hasn't changed... my problem is that it's a 16 bit Dos app so it's a little harder than when programming for windows. If you have any ideas on this I would be greatful.

Regards,
C.

I have to say it's not an area which has occurred to me before. Short of strewing invariant code sequences throughout the function you're testing against and checking every single one I can't think of any good way round it, sorry.
>> It's a little hard to explain so I won't clutter you

But to give you ideas what to do, we have to know what or whom to protect against ...

======
Werner
griessh:
Nice try, but no it doesn't matter. My question is simple:

How do I make sure a function is always compiled into the same codes within the executable?

It's not relavent who I am trying to "protect" the code against because ultimately I am still trying to achieve the same thing and also it's not "protection" of the function I am trying to achieve. If it was to be "completely" secure against hackers etc. then I would not be using this method. What I am trying to do is check the function to ensure it hasn't changed, not "protect" it against intrusion.
If you are determined to get an answer lets just say that if a virus intrudes I want to know if it has affected this function. Any more than this I do not need. I know that ultimately a hacker has the ability to change the CRC checking procedure. I do not care. I am aware that regardless of what CRC the function may ACTUALLY have, a hacker can make the "correct" sum be returned. I do not care. I know that a hacker can potentially make the system assume that any CRC is correct. I do not care. This is all too much detail. All I want to do is as stated in my original question. All the other amenieties I will worry about if and when neccessary.

Viruses never, in my experience, modify code in the MIDDLE of an EXE. What they do is append themselves to the beginning of the EXE, do their work (being the first part of the EXE which is run), then issue a jump to the first instruction of the original EXE file. The original EXE code is completely untouched, unless the virus is slightly buggy and doesn't manage to cleanly install itself, in which case the EXE usually crashes.
That wasn't my point. My point was it doesn't matter what changes the function. What matters is that the function remains intact. Talking about how virii work is veering from my question. Fair enough, I brought up the issue by taking a virus as an example so I apologise, so lets not discuss it. Even talking about protection of the exe is veering from the subject. That was not my question.

My issue is that I don't want the function to change withing the actual exe file when I change the source code in a DIFFERENT area and recompile/link. If anyone can give me ideas on this I will be delighted to read it.
>> How do I make sure a function is always compiled into the same codes within the executable?

(Almost) impossible in most compilers
- VC++ uses a kind of "fuzzy optimizer", actually trying different code sequences and evaluating which one runs faster. A side effect of this is that usually no two compilations of a project are identical.
You could get around this by disabling all optimizations for this function - you seem to be aware of that.

- adresses of global symbols change
- absolute jump targets
you could get around these only by not referencing globals, and by placing the entire function in a separate DLL - which probably destroys your idea of security.

The other option would be writing the function body comlpetely in ASM, only using relative jumps (good luck!)

As the other guys I think your view of security is flawed from the very beginning. Against what do you want to protect yourself? Accidental change? Code breaking attempts? What does "intact" mean?
Please excuse me if I say this smells fishy - you want something very unusual and are not willing to tell us why.


> Please excuse me if I say this smells fishy

How does it smell fishy? I actually can't see any reason why it smells fishy apart from the fact that people are insistent in finding out more than my actual question.

> I think your view of security is flawed from the very beginning

My question was nothing to do with security. It was:
"Is there any way that you can say "THIS FUNCTION MUST BE COMPILED/LINKED INTO THE SAME CODES EVERY TIME"?"

I made the mistake of mentioning the fact that I have to do security checks on our function. BUT in fact if you read the response directly after griessh made a point you will see that in fact I'm not even worried about security of a high level:

> If it was to be "completely" secure against hackers etc.
> then I would not be using this method

One of the reasons we are doing this is people actually maliciously changing the source code or accidentally changing the source code and then recompiling/linking.

Any way it looks as if it can't be done unless you spend alot of time and effort on it so thanks for your points. I am going to accept an answer as I think "pjknibbs" actually was the first to point out the "possible" way I could go about doing this. Taking the example code I gave him he actually answered my question. If anyone has any objections then be quick. I will accept his answer before the day is out.
>> "Is there any way that you can say "THIS FUNCTION MUST BE COMPILED/LINKED INTO THE SAME CODES EVERY TIME"?"

That's a different twist now! But at least very easy to answer: NO! There is now ay to force a C compiler to create the exacy same code each time you recompile.

======
Werner
>> That's a different twist now!

Read my original post and you will see that the mentioned question was ALWAYS the same. It was the first question asked in my original post. It was the only question asked in my original post. So no, it wasn't a different twist.

If we read pjknibbs post he said:

>> However, I can't see this being a particularly useful security check...

And I agree with him, BUT my reply was:

>> Ok, the issue with the hacker is not really an issue in
>> our case. It's not the actual reason we are trying to
>> secure the system. It's a little hard to explain so I
>> won't clutter you with uninteresting details.

And this ultimately started the question about security from you (griessh) which was NEVER part of my original question. The only twist was from the original question to the questioning of the point of this method of security. It's not even security. It's just a check on the code. My issue with checking the exe was the code changing when we change source code in a completely different area of the source than the important code in question.

Which brings me back to pjknibbs answer. He was the first to make a valid suggestion, although peterchen did add a very good post. So I am accepting pjknibbs comment as my answer.
Then please accept his comment as an answer ... Just click that button next to his comment, so we can close this question.

======
Werner
You're not the one I'm waiting for an objection off. But thanks for explaining the intricate procedure of cllicking on a button. I will close this question before the day is out, so don't you worry your little head about it!
Sorry, it was not my intention to attack or insult you in any way, but I saw the comment "I accept xxx's suggestion" so often. After that nothing happened and in the end many weeks and months later one of the moderators had to force-accept the comment. My mistake not to check about your EE status ...

======
Werner