The curious case of a “register” variable

MalwareResearch
3 min readAug 2, 2021

I like looking at the concepts of a programming language from the process memory perspective. This weekend, I was looking at a disassembly block of a simple function. This block was very trivial doing nothing but printing two integer variable to the console. However, there was a minute anomaly; one of the two integer variables was stored in a register (EBX) and the other one was stored in a memory location. Looking at this, it occurred to me that it is strange for a local variable to be stored in the register. Let’s take a look at the disassembly.

Disassembly of the function showing the local variable is stored in register instead of memory
Disassembly block showing one of the variable stored in register

Enter the “register” keyword

ANSI C provides the keyword “register” to tell the compiler that the variable declared as “register” to be stored in register instead of memory address. Ideally, this is a provision built into the language to mark certain local variables which are expected to be used more frequently during code execution hence to save time and thereby to increase performance, such variable can be marked as “register int” instead of “int”.

If you try to get the address of the variable using address of operator (&), your code won’t compile even though sometimes, the compiler can ignore the variable to be treated as “register” variable.

How does this behaves in different platforms (different compilers)

Ubuntu 21.04–64bit: the gcc compiler, honours the “register” keyword and when the code is executed, we can examine the contents of the memory of the variable and for the register integer, the value could not be obtained via memory pointer.

macOS Catalina — 64bit: the apple clang, unlike the gcc compiler of ubuntu does not honour the “register” keyword and it is evident by both static and dynamic analysis. Dynamically, during runtime, the value of the register int can be obtained via pointer dereferencing. Statically, the disassembly of a macho file shows the variable stored in memory instead of register.

Similarly, I did the analysis for few other platforms and tabulated the results as follows

When the “register” keyword is not honoured, the effect can also be confirmed via frida as well through instrumentation

Reading the value of the variable from memory location

The lab environment for running static and dynamic analysis:

Conclusion:

It’s fascinating how granular details appear so crisp when viewed from a Reverse Engineer’s lens and it helps to get a cross platform perspective added to the reverse engineering tasks to build a robust RE/RCE experience.

--

--