0

I was playing around with Intel Pin and OllyDbg. And now I came up with the next question. Imagine we have PE32 executable that are able to run on both Windows 7 and Windows 10 (or any other versions of Windows). If I will use the same disassembler on both OS's will it produce the same assembly code for the same binary? (I don't have a possibility to check it right now) If yes, does this mean that if executable doesn't rely on some very version-specific functions of OS it will produce the same CPU and memory activity (if we have similar hardware with different OS versions) while running under different OS versions? What about the same OS but different CPU's?

In other words will the following code result in the same activity under different OS's on the same hardware, and under same OS but diferent hardware?

MOV EBX, [VAR_NAME]     
MOV [EBX], 110  

Thank you.

0

Yes, that code will always do the same thing, for some reasonable definition of "same".

If it didn't, no windows 7 program would be able to work with windows 8, and no windows 8 program would be able to work with windows 10. As long as programs only use documented OS APIs, Microsoft "guarantees" that they behave the same over a variety of Windows versions.

Of course, there are differences; Windows 10 GUIs look quite different from Windows 7 GUIs. So you could say your program behaves differently; that's because the business logic of your program is within the program itself; the window-drawing-and-decoration stuff is done in Windows libraries. That's why i said "reasonable definition" of "same".

Also, different OSes may lay out memory differently; the address that VAR_NAME refers to might be quite different between Windows 7 and Windows 10. In fact, since the introduction of ASLR, the address may - and in most cases will - change if you run the same program twice on the same machine. All that the OS guarantees is that during one single invocation of the program, the address will not change. Which means all your [VAR_NAME] references will use the same chunk of memory, which is really all your program cares about.

Next, Windows uses virtual addressing for its processes, which means the address your program sees has nothing (easily discernible) to do with the actually used memory address. The physical page your variable is mapped to may change, repeatedly, while your program is running. So again, lots of things that happen may be different, but your program won't notice (unless it tries hard to).

And on the hardware level, lots of things are different as well between CPUs; for example, they have different cache implementations. Which means one CPU might actually access memory every time you read your variable, while another accesses it only once and keeps it in cache. So again, lots of things that happen can be different.

The good new is, your program doesn't want or need to care about it; the OS hides this stuff from your program. From within your program, your instructions always do the same thing - they set a variable to 110, and unless something changes it, it will be 110 the next time you read it. Which is, in fact, all that a normal program needs to know.

You also asked if the disassembly will always be the same. Yes it will, in almost all cases. The same executable will always have the same content (assuming no malware changes stuff ...) which translates to the same assembly. However, some executable formats will allow you to combine more than one executable into one simple file. Apple did this when they moved from one architecture to another. So if you have one of those binaries, it will contain two versions of the same program, one for the PowerPC architecture, and one for the x64 architecture, which, of course, translate to very different disassembled code. But this is not something that should concern you while you're working with Windows. (I seem to remember MS had something similar with Windows 2000 which suported various architectures, but i don't have a reference right now, so i may be wrong; also, this hasn't been a thing for at least 10 years now).

  • Thank you for great answer. However after reading I have more justified question: "And on the hardware level, lots of things are different as well between CPUs" does this mean that depending on Instruction execution flow of a particular CPU MOV EBX, [VAR_NAME] can result in either 2X2bytes read operations or 1X4bytes read operation? Is there any place where I can read about how memory-related operations work on different CPUs (x86 compatible, but different versions)? – aGGeRReS May 10 '16 at 14:19
  • Unless you're a) planning to write your own OS, or b) trying to use a scope to check what's going on on the address/data bus, this probably isn't very relevant to you. And, new CPUs typically fill their cache with larger chunks of data, so you won't see any cycles that correspond exactly to a specific processor instruction. If you want to learn about that, start with googling for "x86 memory controller", but be prepared to work through a lot of theory before being able to do anything "useful". – Guntram Blohm May 10 '16 at 15:22
  • No, I'm not planning to my own OS. Just pure interest. Allright, if we will not take into account caching, e.g. CPU has no cache, or cache is fully transparent and synchronized during each access, will that mean that MOV EBX, [VAR_NAME] will load (in term of number of requests) memory equally regardless of a) OS type b) x86 compatible CPU model? – aGGeRReS May 10 '16 at 23:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.