CHAPTER 19. MANIPULATING SPECIFIC BIT(S) CHAPTER 19. MANIPULATING SPECIFIC BIT(S)
C/C++ expression Power of two Decimal form Hexadecimal form
1 ≪ 0 1 1 1
1 ≪ 1 21 2 2
1 ≪ 2 22 4 4
1 ≪ 3 23 8 8
1 ≪ 4 24 16 0x10
1 ≪ 5 25 32 0x20
1 ≪ 6 26 64 0x40
1 ≪ 7 27 128 0x80
1 ≪ 8 28 256 0x100
1 ≪ 9 29 512 0x200
1 ≪ 10 210 1024 0x400
1 ≪ 11 211 2048 0x800
1 ≪ 12 212 4096 0x1000
1 ≪ 13 213 8192 0x2000
1 ≪ 14 214 16384 0x4000
1 ≪ 15 215 32768 0x8000
1 ≪ 16 216 65536 0x10000
1 ≪ 17 217 131072 0x20000
1 ≪ 18 218 262144 0x40000
1 ≪ 19 219 524288 0x80000
1 ≪ 20 220 1048576 0x100000
1 ≪ 21 221 2097152 0x200000
1 ≪ 22 222 4194304 0x400000
1 ≪ 23 223 8388608 0x800000
1 ≪ 24 224 16777216 0x1000000
1 ≪ 25 225 33554432 0x2000000
1 ≪ 26 226 67108864 0x4000000
1 ≪ 27 227 134217728 0x8000000
1 ≪ 28 228 268435456 0x10000000
1 ≪ 29 229 536870912 0x20000000
1 ≪ 30 230 1073741824 0x40000000
1 ≪ 31 231 2147483648 0x80000000
These constant numbers (bit masks) very often appear in code and a practicing reverse engineer must be able to spot them
quickly. You probably haven’t to memorize the decimal numbers, but the hexadecimal ones are very easy to remember.
These constants are very often used for mapping flags to specific bits. For example, here is excerpt fromssl_private.h
from Apache 2.4.6 source code:
/**
- Define the SSL options
*/
#define SSL_OPT_NONE (0)
#define SSL_OPT_RELSET (1<<0)
#define SSL_OPT_STDENVVARS (1<<1)
#define SSL_OPT_EXPORTCERTDATA (1<<3)
#define SSL_OPT_FAKEBASICAUTH (1<<4)
#define SSL_OPT_STRICTREQUIRE (1<<5)
#define SSL_OPT_OPTRENEGOTIATE (1<<6)
#define SSL_OPT_LEGACYDNFORMAT (1<<7)
Let’s get back to our example.
TheIS_SETmacro checks bit presence ina. TheIS_SETmacro is in fact the logical AND operation (AND) and it returns 0
if the specific bit is absent there, or the bit mask, if the bit is present.The if()operator in C/C++ triggers if the expression in
it is not zero, it might be even 123456, that is why it always works correctly.
19.5.1 x86
MSVC
Let’s compile (MSVC 2010):
Listing 19.27: MSVC 2010