Вы находитесь на странице: 1из 367

reverse engineering

<dennis@yurichev.com>

cbnd
c
2013,
.
Creative Commons
Attribution-NonCommercial-NoDerivs (
) 3.0 . ,
http://creativecommons.org/licenses/by-nc-nd/3.0/.
(16 2014 .).
, , ,
http://yurichev.com/RE-book.html
twitter
, : @yurichev_ru, .


reverse engineering !
( 2014).

: <dennis@yurichev.com>

0.1
0.2 . . .
0.3 -1 . . . . .
0.4 . . . . . . .
0.5 . . . .
0.6 . . . .
0.6.1

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

vii
vii
vii
vii
viii
viii
viii
viii

1
1.1 Hello, world! . . . . . . . . . . . . . . . . . . . .
1.1.1 x86 . . . . . . . . . . . . . . . . . . . . .
1.1.2 ARM . . . . . . . . . . . . . . . . . . . . .
1.2 . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 ? . . . . . .
1.3 printf() . . . .
1.3.1 x86 . . . . . . . . . . . . . . . . . . . . .
1.3.2 ARM: 3 printf() . . . . .
1.3.3 ARM: 8 printf() . . . .
1.3.4 . . . . . . . . . . . . . . . . . . . .
1.4 scanf() . . . . . . . . . . . . . . . . . . . . . . . .
1.4.1 . . . . . . . . . . . . . . .
1.4.2 x86 . . . . . . . . . . . . . . . . . . . . .
1.4.3 ARM . . . . . . . . . . . . . . . . . . . . .
1.4.4 . . . . . . . . .
1.4.5 scanf() . . . . . . .
1.5 . . . . . . . .
1.5.1 x86 . . . . . . . . . . . . . . . . . . . . .
1.5.2 ARM . . . . . . . . . . . . . . . . . . . . .
1.6 .
1.7 . . . . . . . . . . . . . . . . . . . . . .
1.8 . . . . . . . . . . . . . . . .
1.8.1 x86 . . . . . . . . . . . . . . . . . . . . .
1.8.2 ARM . . . . . . . . . . . . . . . . . . . . .
1.9 switch()/case/default . . . . . . . . . . . . . . . .
1.9.1 . . . . . . . . . . .
1.9.2 . . . . . . . . . . . . . . . .
1.10 . . . . . . . . . . . . . . . . . . . . . . . .
1.10.1 x86 . . . . . . . . . . . . . . . . . . . . .
1.10.2 ARM . . . . . . . . . . . . . . . . . . . . .
1.10.3 - . . . . . . . . . . . . . . . .
1.11 strlen() . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

1
1
1
4
9
9
13
13
14
15
18
18
19
19
20
21
23
25
25
27
28
29
30
30
32
34
34
37
42
42
45
46
46

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

ii

1.12

1.13

1.14

1.15

1.16

1.17
1.18
1.19

1.20

1.21
1.22

1.11.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.11.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.12.1 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.12.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.12.3 . . . . . . . . . . . . . . . . . .
FPU . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.13.1 . . . . . . . . . . . . . . . . . . . . . .
1.13.2
1.13.3 . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.14.1 . . . . . . . . . . . . . . . . . . . . . .
1.14.2 . . . . . . . . . . . . . . . . . .
1.14.3 . . . . . . . . . . .
1.14.4 . . . . . . . . . . . . . . . .
1.14.5 . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.15.1 - . . . . . . . . . . . . . . .
1.15.2 / . . . . . . . . . . .
1.15.3 . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.15.4 CRC32 . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.16.1 SYSTEMTIME . . . . . . . . . . . . . . . . . . .
1.16.2 malloc() . . . .
1.16.3 struct tm . . . . . . . . . . . . . . . . . . . . . . . . . .
1.16.4 . . . . . . . . . . . . . . .
1.16.5 . . . . . . . . . . . . . . . . . .
1.16.6 . . . . . . . .
(union) . . . . . . . . . . . . . . . . . . . . . . .
1.17.1 . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
1.18.1 GCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.19.1 . . . . . . . . . . . . . . . . . . . . . . .
1.19.2 strlen() SIMD . . . . . .
64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.20.1 x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.20.2 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C99 restrict . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Inline- . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 ++
2.1 . . . . . . . . . . . . . . . . . . .
2.1.1 . . . . . . . . . . . . . .
2.1.2 . . . . .
2.1.3 . . . . . . . . . .
2.1.4
2.1.5 . . . . . .
2.2 ostream . . . . . . . . . . . . . . . . . .
2.3 References . . . . . . . . . . . . . . . . .
2.4 STL . . . . . . . . . . . . . . . . . . . . .
2.4.1 std::string . . . . . . . . . . . . .
2.4.2 std::list . . . . . . . . . . . . . .
2.4.3 std::vector . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

iii

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . 46
. . . . . . 49
. . . . . . 51
. . . . . . 51
. . . . . . 52
. . . . . . 54
. . . . . . 54
. . . . . . 55
. . . . . . 58
. . . . . . 60
. . . . . . 67
. . . . . . 67
. . . . . . 70
. . . . . . 73
. . . . . . 76
. . . . . . 77
. . . . . . 79
. . . . . . 79
. . . . . . 83
. . . . . . 86
. . . . . . 88
. . . . . . 91
. . . . . . 91
. . . . . . 93
. . . . . . 95
. . . . . . 99
. . . . . . 102
. . . . . . 103
. . . . . . 108
. . . . . . 108
. . . . . . 110
. . . . . . 112
. . . . . . 113
. . . . . . 114
. . . . . . 119
. . . . . . 122
. . . . . . 122
. . . . . . 128
. . . . . . 128
. . . . . . 131

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

133
133
133
137
140
142
144
147
148
148
149
155
163

2.4.4

std::map std::set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

3 -
3.1 . . . . . . . . . . . . . . .
3.2 npad . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 . . . . . . . . . . . . .
3.3.1 integer . . . . . . . . . . . . . .
3.4
3.4.1 cdecl . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.2 stdcall . . . . . . . . . . . . . . . . . . . . . . . .
3.4.3 fastcall . . . . . . . . . . . . . . . . . . . . . . .
3.4.4 thiscall . . . . . . . . . . . . . . . . . . . . . . .
3.4.5 x86-64 . . . . . . . . . . . . . . . . . . . . . . .
3.4.6 float, double .
3.5 - . . . . . . . . . . . . . . . .
3.5.1 Windows . . . . . . . . . . . . . . . . . . . . . .
3.6 Thread Local Storage . . . . . . . . . . . . . . . . . . . .
3.7 LD_PRELOAD Linux . . . . . . . . . . . . . . .
3.8 Itanium . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.9 basic block- . . . . . . . . . . . . . . .
3.9.1 Profile-guided optimization . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

179
179
179
181
181
181
181
181
182
182
183
185
185
187
188
188
190
192
192

4
4.1 . . . . . . . . . . . . . . . . . . .
4.1.1 - Windows API . . . . .
4.1.2 tracer: -
4.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 assert() . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1 Magic numbers . . . . . . . . . . . . . . . . . . . . .
4.4.2 . . . . . . . . . . . . . . . . . . . .
4.5 . . . . . . . . . . . . . . . . . .
4.6 . . . . . . . . . . . . . . .
4.6.1 . . . . .
4.7 magic numbers . . . . .
4.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9 , , . . . . . . . .
4.9.1 . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

195
195
196
196
197
197
198
198
199
199
201
201
201
202
202
202

5
5.1 . . . . . . . . . . .
5.1.1 Win32 PE . . . . . . . . . . .
5.2 (syscall-) . . .
5.2.1 Linux . . . . . . . . . . . . .
5.2.2 Windows . . . . . . . . . . .
5.3 Windows NT:

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

203
203
203
209
210
210
210

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

6
213
6.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
6.0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

iv

7
7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1 #1: MacOS Classic PowerPC . . . . . . . . . . . . . . .
7.1.2 #2: SCO OpenServer . . . . . . . . . . . . . . . . . . . .
7.1.3 #3: MS-DOS . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 QR9:
7.3 SAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.1 SAP . . .
7.3.2 SAP 6.0 . . . . . . . . . . . . . . .
7.4 Oracle RDBMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4.1 V$VERSION Oracle RDBMS . . . . . . . . . . . . . . .
7.4.2 X$KSMLRU Oracle RDBMS . . . . . . . . . . . . . . .
7.4.3 V$TIMER Oracle RDBMS . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

214
. . . . . . 214
. . . . . . 214
. . . . . . 221
. . . . . . 228
. . . . . . 234
. . . . . . 259
. . . . . . 259
. . . . . . 269
. . . . . . 272
. . . . . . 272
. . . . . . 279
. . . . . . 281

8
8.1 Compiler intrinsic . . . . .
8.2
8.3 OpenMP . . . . . . . . . .
8.3.1 MSVC . . . . . . .
8.3.2 GCC . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

285
285
285
286
287
289

9
9.1 . . . . . . . . .
9.1.1 Windows . .
9.1.2 /++ . . .
9.1.3 x86 / x86-64
9.1.4 ARM . . . . .
9.2 . . . . . . . . .
9.2.1 Windows . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

292
292
292
292
292
292
292
292

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

293
293
293
294
297
299
302
303
305
308
310
312
312
312
312
318
318
318
319
319
319
319

10
10.1 . . .
10.1.1 1.1 .
10.1.2 1.2 .
10.1.3 1.3 .
10.1.4 1.4 .
10.1.5 1.5 .
10.1.6 1.6 .
10.1.7 1.7 .
10.1.8 1.8 .
10.1.9 1.9 .
10.1.10 1.10
10.1.11 1.11
10.2 . .
10.2.1 2.1 .
10.2.2 2.2 .
10.2.3 2.3 .
10.2.4 2.4 .
10.2.5 2.5 .
10.2.6 2.6 .
10.2.7 2.7 .
10.3 crackme / keygenme

.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

11
11.1 . . .
11.1.1 1.1 .
11.1.2 1.2 .
11.1.3 1.3 .
11.1.4 1.4 .
11.1.5 1.5 .
11.1.6 1.6 .
11.1.7 1.7 .
11.1.8 1.8 .
11.1.9 1.9 .
11.1.10 1.11
11.2 . .
11.2.1 2.1 .
11.2.2 2.2 .
11.2.3 2.3 .
11.2.4 2.4 .
11.2.5 2.5 .
11.2.6 2.6 .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

320
. . . . . . 320
. . . . . . 320
. . . . . . 320
. . . . . . 320
. . . . . . 321
. . . . . . 321
. . . . . . 322
. . . . . . 322
. . . . . . 323
. . . . . . 323
. . . . . . 323
. . . . . . 324
. . . . . . 324
. . . . . . 324
. . . . . . 324
. . . . . . 324
. . . . . . 324
. . . . . . 324

325
11.3 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

11.4 . . . . . . . . . . . . . . . . . . . . . . . . .
11.5 x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.5.1 . . . . . . . . . . . . . . . . . . . . . . . . .
11.5.2 . . . . . . . . . . . . . . .
11.5.3 FPU- . . . . . . . . . . . . . . . . . . . . . . . . .
11.5.4 SIMD- . . . . . . . . . . . . . . . . . . . . . . . .
11.5.5 . . . . . . . . . . . . . . . . . . . .
11.5.6 . . . . . . . . . . . . . . . . . . . . . . . . . .
11.6 ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.6.1 . . . . . . . . . . . . . . .
11.6.2 Current Program Status Register (CPSR) . . . . . . . . . .
11.6.3 VPF ( ) NEON

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

326
326
326
326
326
330
332
332
333
344
344
345
345

346

350

352

354

vi

0.

() reverse engineering ,
/++ x86 (, ,
) ARM.
reverse engineering : 1)
; 2) ; 3) .

0.1

x86, ARM.

0.2

Oracle RDBMS, Itanium, , LD_PRELOAD, , ELF2 , PE win32, x86-64, , , TLS3 , - (PIC), profileguided optimization, C++ STL, OpenMP (8.3).

0.3

Q: ?
A: : , .
Q: ?
A: , , 4 .
Q: ?
A: , /++ .
Q: ?
A: CPU5 . ,
, CPU
6 . , , ISA7 , , .., CPU, .
Q: ?
A: , , ( ) 8 .
2

, Linux *NIX
Thread Local Storage
4

5
Central processing unit
6
: [8]
7
Instruction Set Architecture ( )
8
(2013) malware
3

vii

0.4.
0.
Q: reverse engineer-?
A: reddit RE9 hiring thread (2013 Q3), .

0.4

reverse engineer . , (reverse engineering), /++.


, Skype , , . .

0.5

herm1t , Avid , Beaver , , Lstar , , Logxen , Shell Rocket, Arnaud Patard (rtp
#debian-arm IRC), github.com .
LATEX: .

0.6

, () .
, , 10
(LaTeX), .
: MIPS, Objective-C,
Visual Basic, anti-debugging tricks, Windows NT kernel debugger, Java, .NET, Oracle RDBMS.
,
.
http://yurichev.com/crowdfunding.
html
!
- .
? , , ,
. Wikipedia MSDN11 , . -
, . ,
. , ,
, , , .
,
: https://github.com/dennis714/RE-for-beginners/commits/master.
rolling release, Linux Gentoo.
( ) , . , , 10 . ,
, ChangeLog, . ,
, , /twitter 12 .

0.6.1

3 * .

http://www.reddit.com/r/ReverseEngineering/
https://github.com/dennis714/RE-for-beginners
11
Microsoft Developer Network
12
http://blog.yurichev.com/ https://twitter.com/yurichev_ru
10

viii

1.


, ++, ,
. . ,
/++ ,
, , .
- , .

1.1

Hello, world!

The C programming Language [14]:


#include <stdio.h>
int main()
{
printf("hello, world");
return 0;
};

1.1.1

x86

MSVC
MSVC 2010:
cl 1.cpp /Fa1.asm

( /Fa )
Listing 1.1: MSVC 2010
CONST
SEGMENT
$SG3830 DB
hello, world, 00H
CONST
ENDS
PUBLIC _main
EXTRN
_printf:PROC
; Function compile flags: /Odtp
_TEXT
SEGMENT
_main
PROC
push
ebp
mov
ebp, esp
push
OFFSET $SG3830
call
_printf
add
esp, 4
xor
eax, eax
pop
ebp
ret
0
_main
ENDP
_TEXT
ENDS

1.1. HELLO, WORLD!


1.
MSVC Intel- . Intel- AT&T .
1.obj, 1.exe.
, : CONST ( -) _TEXT ( ).
hello, world /++ const char*, .
- , $SG3830.
, /++ .
_TEXT, : main().
main(), , 1 .
printf(): CALL _printf.
, ( ) PUSH .
printf() main(), ( ) .
, ( ESP) .
ADD ESP, 4 4 ESP.
4? , 32- , 4 . x64- 8
.
ADD ESP, 4 POP , - 2 .
, Intel C++ Compiler, , ADD POP ECX ( Oracle RDBMS, ),
, ECX.
, POP ECX (1 3).
(1.2).
printf(), /++ return 0 0
main().
XOR EAX, EAX
XOR, , , 3 ,
MOV EAX, 0 (2 5).
, SUB EAX, EAX, ,
EAX EAX, 0 .
RET . ,
/++ CRT4 , , , .
GCC
GCC 4.4.1 Linux: gcc 1.c -o 1
IDA5 . main().
(IDA, MSVC, Intel-).
N.B. GCC -S
-masm=intel
Listing 1.2: GCC
main

proc near

var_10

= dword ptr -10h


push
mov
and
sub
mov

ebp
ebp,
esp,
esp,
eax,

esp
0FFFFFFF0h
10h
offset aHelloWorld ; "hello, world"

(3.1).
, ,
3
http://en.wikipedia.org/wiki/Exclusive_or
4
C runtime library
5
Interactive Disassembler
2

1.1. HELLO, WORLD!


mov
call
mov
leave
retn
endp

main

1.
[esp+10h+var_10], eax
_printf
eax, 0

. hello, world , EAX,


. AND ESP, 0FFFFFFF0h
ESP 16- ,
(
4 16)6 .
SUB ESP, 10h 16 . , , 4.
16 .
( ) PUSH.
var_10 printf(). .
printf().
MSVC, GCC MOV EAX, 0
.
LEAVE MOV ESP, EBP POP EBP
EBP .
, .., ESP EBP ( MOV
EBP, ESP / AND ESP, ...).
GCC: AT&T
, AT&T- .
UNIX-.
Listing 1.3: GCC 4.7.3
gcc -S 1_1.c

:
Listing 1.4: GCC 4.7.3
.file
"1_1.c"
.section
.rodata
.LC0:
.string "hello, world"
.text
.globl main
.type
main, @function
main:
.LFB0:
.cfi_startproc
pushl
%ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl
%esp, %ebp
.cfi_def_cfa_register 5
andl
$-16, %esp
subl
$16, %esp
movl
$.LC0, (%esp)
call
printf
movl
$0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
6

Wikipedia:

1.1. HELLO, WORLD!

1.

.size
main, .-main
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
.section
.note.GNU-stack,"",@progbits

( ). . , ,
( .string, , ).
7:
Listing 1.5: GCC 4.7.3
.LC0:
.string "hello, world"
main:
pushl
movl
andl
subl
movl
call
movl
leave
ret

%ebp
%esp, %ebp
$-16, %esp
$16, %esp
$.LC0, (%esp)
printf
$0, %eax

Intel AT&T :
.
Intel-: <> < > <->.
AT&T-: <> <-> < >.
, : Intel-,
(=) , AT&T-,
() 8 .
AT&T: (%), ($).
.
AT&T: , :
l long (32 )
w word (16 )
b byte (8 )
: , IDA. :
0FFFFFFF0h $-16. : 16 0x10 . -0x10 0xFFFFFFF0 ( 32- ).
: 0 MOV XOR. MOV
. ( ), load - .

1.1.2

ARM

ARM, : embedded- Keil


Release 6/2013 Apple Xcode 4.6.3 ( LLVM-GCC 4.2 ),
ARM- SOC9 iPod/iPhone/iPad, Windows 8
Windows RT10 Raspberry Pi.
7

, , GCC: -fno-asynchronous-unwind-tables
, (, memcpy(), strcpy())
Intel-: , -.
9
System on Chip
10
http://en.wikipedia.org/wiki/List_of_Windows_8_and_RT_tablet_devices
8

1.1. HELLO, WORLD!


Keil + ARM

1.

, Keil:
armcc.exe --arm --c90 -O0 1.c

armcc Intel, ARM11 , ,


IDA.
Listing 1.6: Keil + ARM + IDA
.text:00000000
.text:00000000
.text:00000004
.text:00000008
.text:0000000C
.text:00000010

main
10
1E
15
00
10

40
0E
19
00
80

2D
8F
00
A0
BD

E9
E2
EB
E3
E8

.text:000001EC 68 65 6C 6C+aHelloWorld

STMFD
ADR
BL
MOV
LDMFD

SP!, {R4,LR}
R0, aHelloWorld ; "hello, world"
__2printf
R0, #0
SP!, {R4,PC}

DCB "hello, world",0

; DATA XREF: main+4

- ARM, . ARM : ARM thumb. (ARM)


32 ( 4 ). (thumb) 16 ( 2 ) 12 . thumb ,
1) ; 2) 16- .
: thumb , ,
8- , ,
ARM , thumb-. ARMv7,
thumb-2, thumb . thumb-2 ARM thumb. . thumb-2
,
ARM. ARM
. iPod/iPhone/iPad
thumb-2, Xcode .
4 .
, ARM thumb.
, STMFD SP!, {R4,LR}13 , PUSH x86, (R4 LR14 ) . , ,
armcc, , PUSH {r4,lr}. , PUSH thumb, , ,
IDA.
, R4 LR ,
SP1516 , SP, , .
, PUSH thumb, , . , x86 . ,
STMFD PUSH ( , ),
SP, .
ADR R0, aHelloWorld PC17 , hello, world . PC, ? , 18 , -
11

, PUSH/POP ARM
, , ( )
. switch() (1.9.2).
13
Store Multiple Full Descending
14
Link Register
15
Stack Pointer
16
ESP, RSP x86
17
Program Counter
18
(3.5)
12

1.1. HELLO, WORLD!


1.
. ADR , . , ,
. ( PC) -.
BL __2printf19 printf().
:
BL (0xC) LR;
printf(), PC20 .
, printf() , , , , LR.
RISC21 - ARM CISC22 - x86,
23 .
, 32- , , 32- BL, 24- . , -
ARM 4 (32 ),
4, 2 ( ) . 26 ,
32 .
MOV R0, #024 0 R0. -
0 R0.
LDMFD SP!, R4,PC25 STMFD.
R4 PC, SP. , - ,
POP. N.B. STMFD R4 LR,
LDMFD R4 PC. , LR
, .
, main() ,
printf(). , , PC, ,
, . main()
/++, , - CRT, - .
DCB , ASCII-, DB
x86-.
Keil: thumb
Keil thumb:
armcc.exe --thumb --c90 -O0 1.c

( IDA):
Listing 1.7: Keil + thumb + IDA
.text:00000000
.text:00000000
.text:00000002
.text:00000004
.text:00000008
.text:0000000A

main
10
C0
06
00
10

B5
A0
F0 2E F9
20
BD

.text:00000304 68 65 6C 6C+aHelloWorld

PUSH
ADR
BL
MOVS
POP

{R4,LR}
R0, aHelloWorld ; "hello, world"
__2printf
R0, #0
{R4,PC}

DCB "hello, world",0

19

Branch with Link


EIP, RIP x86
21
Reduced instruction set computing
22
Complex instruction set computing
23
(1.2)
24
MOVe
25
Load Multiple Full Descending
20

; DATA XREF: main+2

1.1. HELLO, WORLD!


1.
(16-) , , , thumb. BL. , 16- . PC
, printf(), 16- , . 16- 10 ,
11 . , thumb- 2 ( 16 ).
, thumb- .
, . , , thumb- BL
2 .
: PUSH POP STMFD/LDMFD,
SP . ADR . MOVS
0 R0 .
Xcode (LLVM) + ARM
Xcode 4.6.3 ,
, : -O3.
Listing 1.8: Xcode (LLVM) + ARM
__text:000028C4
__text:000028C4
__text:000028C8
__text:000028CC
__text:000028D0
__text:000028D4
__text:000028D8
__text:000028DC
__text:000028E0

_hello_world
80
86
0D
00
00
C3
00
80

40
06
70
00
00
05
00
80

2D
01
A0
40
8F
00
A0
BD

E9
E3
E1
E3
E0
EB
E3
E8

__cstring:00003F62 48 65 6C 6C+aHelloWorld_0

STMFD
MOV
MOV
MOVT
ADD
BL
MOV
LDMFD

SP!, {R7,LR}
R0, #0x1686
R7, SP
R0, #0
R0, PC, R0
_puts
R0, #0
SP!, {R7,PC}

DCB "Hello world!",0

STMFD LDMFD .
MOV 0x1686 R0,
Hello world!.
R7, [2] frame pointer , .
MOVT R0, #0 0 16 . ,
MOV ARM - 16 , ,
. , ARM
32 . , .
( 16- 31- ) MOVT. ,
, MOV R0, #0x1686
. , .
ADD R0, PC, R0 PC R0,
Hello world!, , - , .
BL puts() printf().
printf() puts(). , printf()
puts().
, printf()
. 26 .
? puts() () 27 .
, puts() stdout .
MOV R0, #0, 0
.
26
27

, puts() \n , .
http://www.ciselant.de/projects/gcc_printf/gcc_printf.html

1.1. HELLO, WORLD!


Xcode (LLVM) + thumb-2

1.

, Xcode 4.6.3 thumb-2, :


Listing 1.9: Xcode (LLVM) + thumb-2
__text:00002B6C
__text:00002B6C
__text:00002B6E
__text:00002B72
__text:00002B74
__text:00002B78
__text:00002B7A
__text:00002B7E
__text:00002B80

_hello_world
80
41
6F
C0
78
01
00
80

B5
F2 D8 30
46
F2 00 00
44
F0 38 EA
20
BD

PUSH
MOVW
MOV
MOVT.W
ADD
BLX
MOVS
POP

{R7,LR}
R0, #0x13D8
R7, SP
R0, #0
R0, PC
_puts
R0, #0
{R7,PC}

...
__cstring:00003E70 48 65 6C 6C 6F 20+aHelloWorld

DCB "Hello world!",0xA,0

BL BLX thumb, , 16- , thumb-2


, 32- . thumb-2 0xFx 0xEx.
IDA , - ARM
: , ( thumb thumb-2 ), , ( ARM) , , (.., endianness).
MOVW, MOVT.W BLX 0xFx.
thumb-2 MOVW R0, #0x13D8 16- R0.
MOVT.W R0, #0 MOVT ,
thumb-2.
, BLX BL. ,
LR puts(),
thumb ARM, . ,
, ( ARM):
__symbolstub1:00003FEC _puts
__symbolstub1:00003FEC 44 F0 9F E5

; CODE XREF: _hello_world+E


LDR PC, =__imp__puts

, : puts()
, ?
( ) .
( DLL Windows,
.so *NIX .dylib Mac OS X). , puts().
(Windows PE .exe, ELF Mach-O) ,
( ) ,
.
, , .
, __imp__puts 32- ,
. LDR 32-
, PC, .
,
, .
, , 32-
. , , , ARM, , .
( thunk-) thumb-.
, ( ARM),
BL thunk-, (, X
8

1.2.
).

1.2

1.

28 .
, + ESP RSP x86, SP ARM,
- .
PUSH POP ( x86 thumb- ARM).
PUSH ESP/RSP/SP 4 32- ( 8 64-),
ESP/RSP/SP .
POP
( ) 4 ( 8).
, - . PUSH -,
POP . . ,
.
ARM, , ,
.
, STMFD29 /LDMFD30 , STMED31 /LDMED32 descending-, ..,
. STMFA33 /LMDFA34 , STMEA35 /LDMEA36 ascending-,
.., .

1.2.1


x86 CALL,
CALL, ( JMP)
.
CALL PUSH address_after_call / JMP..
RET POP tmp / JMP tmp.
:
void f()
{
f();
};

MSVC 2008 :
c:\tmp6>cl ss.cpp /Fass.asm
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
ss.cpp
c:\tmp6\ss.cpp(4) : warning C4717: f : recursive on all control paths, function will cause runtime stack
overflow

. . . :
28

http://en.wikipedia.org/wiki/Call_stack
Store Multiple Full Descending
30
Load Multiple Full Descending
31
Store Multiple Empty Descending
32
Load Multiple Empty Descending
33
Store Multiple Full Ascending
34
Load Multiple Full Ascending
35
Store Multiple Empty Ascending
36
Load Multiple Empty Ascending
29

1.2.

1.

?f@@YAXXZ PROC
; File c:\tmp6\ss.cpp
; Line 2
push
ebp
mov
ebp, esp
; Line 3
call
?f@@YAXXZ
; Line 4
pop
ebp
ret
0
?f@@YAXXZ ENDP

; f

; f

; f

. . . , (/Ox), , ,
37 :
?f@@YAXXZ PROC
; File c:\tmp6\ss.cpp
; Line 2
$LL3@f:
; Line 3
jmp
SHORT $LL3@f
?f@@YAXXZ ENDP

; f

; f

GCC 4.4.1 , .
ARM ARM RA38 , , . Hello, world! (1.1.2), RA LR (link register).
- , LR ,
. , , PUSH R4-R7,LR , POP R4-R7,PC ,
, LR.
, , ARM leaf function39 . , leaf- LR. , , . , ARM
leaf . x86, 40 . , ,
.

x86 cdecl:
push arg3
push arg2
push arg1
call f
add esp, 4*3

.
,
- f():
ESP
ESP+4 arg1
ESP+8 arg2
37



39
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13785.html
40
- , PDP-11 VAX, CALL ( ) 50% ,
- , - [20, Chapter 4, Part II].
38

10

1.2.
ESP+0xA arg3

1.

. (3.4).
, , ,
, .
, .
, , EAX. 41 .
, , x86 ARM
.
, - , . -
( printf())
( %). -
printf("%d %d %d", 1234);

printf() 1234, , .
, - main(): main(), main(int argc, char *argv[])
main(int argc, char *argv[], char *envp[]).
, .. startup- main() :
push
push
push
call
...

envp
argv
argc
main

main() main() , , , ,
. main() main(int argc, char *argv[]), , - . ,
main(int argc), .


.
. . .
x86: alloca()
alloca()42 .
malloc(), .
free() , (3.1) ESP y.
alloca().
, , ESP
ESP . :
#include <malloc.h>
#include <stdio.h>

41
, , 1.4.1 [15, 1.4.1], JMP
. System/360.
42
MSVC, alloca16.asm chkstk.asm C:\Program Files
(x86)\Microsoft Visual Studio 10.0\VC\crt\src\intel

11

1.2.

1.

void f()
{
char *buf=(char*)alloca (600);
_snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3);
puts (buf);
};

( _snprintf() printf(), stdout


(.., ), buf. puts() buf
stdout. , printf(), .)
MSVC (MSVC 2010):
Listing 1.10: MSVC 2010
...
mov
call
mov

eax, 600
; 00000258H
__alloca_probe_16
esi, esp

push
push
push
push
push
push
call

3
2
1
OFFSET $SG2672
600
esi
__snprintf

push
call
add

esi
_puts
esp, 28

; 00000258H

; 0000001cH

...

alloca() EAX, 43 . alloca(), ESP 600 buf.


GCC + Intel GCC 4.4.1 :
Listing 1.11: GCC 4.7.3
.LC0:
.string "hi! %d, %d, %d\n"
f:
push
mov
push
sub
lea
and
mov
mov
mov
mov
mov
mov
call
mov
call
mov
leave
ret

43

ebp
ebp, esp
ebx
esp, 660
ebx, [esp+39]
ebx, -16
; 16-
DWORD PTR [esp], ebx
; s
DWORD PTR [esp+20], 3
DWORD PTR [esp+16], 2
DWORD PTR [esp+12], 1
DWORD PTR [esp+8], OFFSET FLAT:.LC0 ; "hi! %d, %d, %d\n"
DWORD PTR [esp+4], 600
; maxlen
_snprintf
DWORD PTR [esp], ebx
; s
puts
ebx, DWORD PTR [ebp-4]

alloca() , .. compiler intrinsic (8.1)

12

1.3. PRINTF()
1.
GCC + AT&T , AT&T:
Listing 1.12: GCC 4.7.3
.LC0:
.string "hi! %d, %d, %d\n"
f:
pushl
movl
pushl
subl
leal
andl
movl
movl
movl
movl
movl
movl
call
movl
call
movl
leave
ret

%ebp
%esp, %ebp
%ebx
$660, %esp
39(%esp), %ebx
$-16, %ebx
%ebx, (%esp)
$3, 20(%esp)
$2, 16(%esp)
$1, 12(%esp)
$.LC0, 8(%esp)
$600, 4(%esp)
_snprintf
%ebx, (%esp)
puts
-4(%ebp), %ebx

.
N.B. , movl $3, 20(%esp) mov DWORD PTR [esp+20], 3 Intel-
+, AT&T (%).
(Windows) SEH
SEH44 ( ) 45 .

(1.14.2).

1.3

printf()

Hello, world! (1.1), main():


printf("a=%d; b=%d; c=%d", 1, 2, 3);

1.3.1

x86

MSVC 2010 Express, :


$SG3830 DB

a=%d; b=%d; c=%d, 00H

...
push
push
push
push
call
add

3
2
1
OFFSET $SG3830
_printf
esp, 16

; 00000010H

, , , printf()
: .
44
45

Structured Exception Handling


SEH: : http://www.microsoft.com/msj/0197/Exception/Exception.aspx

13

1.3. PRINTF()
1.
, int 32- , , 32 ,
4 .
, 4 . 4 * 4 = 16 16
3 int.
ADD ESP, X ESP , , ,
X 4.
, cdecl- .
. (3.4).
, ,
, :
push a1
push a2
call ...
...
push a1
call ...
...
push a1
push a2
push a3
call ...
add esp, 24

Linux GCC 4.4.1 IDA :


main

proc near

var_10
var_C
var_8
var_4

=
=
=
=

main

push
mov
and
sub
mov
mov
mov
mov
mov
call
mov
leave
retn
endp

dword
dword
dword
dword

ptr
ptr
ptr
ptr

-10h
-0Ch
-8
-4

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 10h
eax, offset aADBDCD ; "a=%d; b=%d; c=%d"
[esp+10h+var_4], 3
[esp+10h+var_8], 2
[esp+10h+var_C], 1
[esp+10h+var_10], eax
_printf
eax, 0

, GCC MSVC . GCC PUSH/POP.

1.3.2

ARM: 3 printf()

ARM : 4 R0-R3, . fastcall (3.4.3)


win64 (3.4.5).
Keil + ARM
Listing 1.13: Keil + ARM
.text:00000014
.text:00000014
.text:00000018
.text:0000001C
.text:00000020

printf_main1
10
03
02
01

40
30
20
10

2D
A0
A0
A0

E9
E3
E3
E3

STMFD
MOV
MOV
MOV

SP!, {R4,LR}
R3, #3
R2, #2
R1, #1

14

1.3. PRINTF()
.text:00000024 1D 0E 8F E2
.text:00000028 0D 19 00 EB
.text:0000002C 10 80 BD E8

ADR
BL
LDMFD

1.
R0, aADBDCD
__2printf
SP!, {R4,PC}

; "a=%d; b=%d; c=%d\n"

, 4 R0-R3, : -
printf() R0, 1 R1, 2 R2 3 R3.
, .
Keil + ARM
Listing 1.14: Keil + ARM
.text:00000014
.text:00000014
.text:00000014
.text:00000018
.text:0000001C
.text:00000020
.text:00000024

EXPORT printf_main1
printf_main1
03
02
01
1E
CB

30
20
10
0E
18

A0
A0
A0
8F
00

E3
E3
E3
E2
EA

MOV
MOV
MOV
ADR
B

R3, #3
R2, #2
R1, #1
R0, aADBDCD
__2printf

; "a=%d; b=%d; c=%d\n"

(-O3) ARM, : B
BL. , , , (,
R0 LR). B , LR, , JMP x86. ?
. : 1) , SP; 2) printf() , . printf(), ,
, LR. LR , ! , printf() . ,
LR, LR. LR, , printf(), , !
.
switch()/case/default , (1.9.1).
Keil + thumb
Listing 1.15: Keil + thumb
.text:0000000C
.text:0000000C
.text:0000000E
.text:00000010
.text:00000012
.text:00000014
.text:00000016
.text:0000001A

printf_main1
10
03
02
01
A4
06
10

B5
23
22
21
A0
F0 EB F8
BD

PUSH
MOVS
MOVS
MOVS
ADR
BL
POP

{R4,LR}
R3, #3
R2, #2
R1, #1
R0, aADBDCD
__2printf
{R4,PC}

; "a=%d; b=%d; c=%d\n"

ARM.

1.3.3

ARM: 8 printf()

, , ,
, 9 ( printf() 8
int):
void printf_main2()
{
printf("a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n", 1, 2, 3, 4, 5, 6, 7, 8);
};

15

1.3. PRINTF()
Keil: ARM
.text:00000028
.text:00000028
.text:00000028
.text:00000028
.text:00000028
.text:00000028
.text:00000028 04
.text:0000002C 14
.text:00000030 08
.text:00000034 07
.text:00000038 06
.text:0000003C 05
.text:00000040 04
.text:00000044 0F
.text:00000048 04
.text:0000004C 00
.text:00000050 03
.text:00000054 02
.text:00000058 01
.text:0000005C 6E
=%d; g=%"...
.text:00000060 BC
.text:00000064 14
.text:00000068 04

1.

printf_main2
var_18
var_14
var_4
E0
D0
30
20
10
00
C0
00
00
00
30
20
10
0F

2D
4D
A0
A0
A0
A0
8D
8C
A0
8D
A0
A0
A0
8F

E5
E2
E3
E3
E3
E3
E2
E8
E3
E5
E3
E3
E3
E2

18 00 EB
D0 8D E2
F0 9D E4

= -0x18
= -0x14
= -4
STR
SUB
MOV
MOV
MOV
MOV
ADD
STMIA
MOV
STR
MOV
MOV
MOV
ADR

LR, [SP,#var_4]!
SP, SP, #0x14
R3, #8
R2, #7
R1, #6
R0, #5
R12, SP, #0x18+var_14
R12, {R0-R3}
R0, #4
R0, [SP,#0x18+var_18]
R3, #3
R2, #2
R1, #1
R0, aADBDCDDDEDFDGD ; "a=%d; b=%d; c=%d; d=%d; e=%d; f

BL
ADD
LDR

__2printf
SP, SP, #0x14
PC, [SP+4+var_4],#4

:
:
STR LR, [SP,#var_4]! LR, ,
printf().
SUB SP, SP, #0x14 SP, ,
0x14 (20) . ,
5 32- printf(), 4
, 5 * 4 = 20 . 4 32- .
5, 6, 7 8 :
5, 6, 7 8 R0, R1, R2 R3 . ADD R12, SP, #0x18+var_14 R12 ,
4 . var_14 , 014, IDA,
, . var_?, IDA, . , R12 + 4.
STMIA R12, R0-R3 R0-R3 ,
R12. STMIA Store Multiple Increment After. Increment After
R12 4 .
4 : 4 R0, , , STR R0,
[SP,#0x18+var_18] . var_18 018, 0, ,
R0 (4) , SP.
1, 2 3 :
(a, b, c) (1, 2, 3 ) R1, R2 R3
printf(), 5 , :
printf():
:
ADD SP, SP, #0x14 SP , ,
. , , ,
.
LDR PC, [SP+4+var_4],#4 PC LR , , .
16

1.3. PRINTF()
Keil: thumb
.text:0000001C
.text:0000001C
.text:0000001C
.text:0000001C
.text:0000001C
.text:0000001C
.text:0000001C 00
.text:0000001E 08
.text:00000020 85
.text:00000022 04
.text:00000024 07
.text:00000026 06
.text:00000028 05
.text:0000002A 01
.text:0000002C 07
.text:0000002E 04
.text:00000030 00
.text:00000032 03
.text:00000034 02
.text:00000036 01
.text:00000038 A0
=%d; g=%"...
.text:0000003A 06
.text:0000003E
.text:0000003E
.text:0000003E 05
.text:00000040 00

1.

printf_main2
var_18
var_14
var_8

= -0x18
= -0x14
= -8

B5
23
B0
93
22
21
20
AB
C3
20
90
23
22
21
A0

PUSH
MOVS
SUB
STR
MOVS
MOVS
MOVS
ADD
STMIA
MOVS
STR
MOVS
MOVS
MOVS
ADR

{LR}
R3, #8
SP, SP, #0x14
R3, [SP,#0x18+var_8]
R2, #7
R1, #6
R0, #5
R3, SP, #0x18+var_14
R3!, {R0-R2}
R0, #4
R0, [SP,#0x18+var_18]
R3, #3
R2, #2
R1, #1
R0, aADBDCDDDEDFDGD ; "a=%d; b=%d; c=%d; d=%d; e=%d; f

F0 D9 F8

BL

__2printf

ADD
POP

SP, SP, #0x14


{PC}

loc_3E
B0
BD

; CODE XREF: example13_f+16

, thumb
: 8 , 5, 6, 7 4 .
Xcode (LLVM): ARM
__text:0000290C
__text:0000290C
__text:0000290C
__text:0000290C
__text:0000290C
__text:0000290C
__text:00002910
__text:00002914
__text:00002918
__text:0000291C
__text:00002920
__text:00002924
__text:00002928
__text:0000292C
__text:00002930
__text:00002934
__text:00002938
__text:0000293C
__text:00002940
__text:00002944
__text:00002948
__text:0000294C
__text:00002950
__text:00002954
__text:00002958

_printf_main2
var_1C
var_C
80
0D
14
70
07
00
04
00
06
05
00
0A
08
01
02
03
10
A4
07
80

40
70
D0
05
C0
00
20
00
30
10
20
10
90
10
20
30
90
05
D0
80

2D
A0
4D
01
A0
40
A0
8F
A0
A0
8D
8D
A0
A0
A0
A0
8D
00
A0
BD

E9
E1
E2
E3
E3
E3
E3
E0
E3
E3
E5
E9
E3
E3
E3
E3
E5
EB
E1
E8

= -0x1C
= -0xC
STMFD
MOV
SUB
MOV
MOV
MOVT
MOV
ADD
MOV
MOV
STR
STMFA
MOV
MOV
MOV
MOV
STR
BL
MOV
LDMFD

SP!, {R7,LR}
R7, SP
SP, SP, #0x14
R0, #0x1570
R12, #7
R0, #0
R2, #4
R0, PC, R0
R3, #6
R1, #5
R2, [SP,#0x1C+var_1C]
SP, {R1,R3,R12}
R9, #8
R1, #1
R2, #2
R3, #3
R9, [SP,#0x1C+var_C]
_printf
SP, R7
SP!, {R7,PC}

, STMFA (Store Multiple Full Ascending)


STMIB (Store Multiple Increment Before) . SP
, .
, . ,
R0 , 0x2918, 0x2920 0x2928,
. ,
, . . ,

17

1.4. SCANF()
1.
MOVT R0, #0 ADD R0, PC, R0 , R0. MOVT R0, #0 MOV R2, #4
, . , , , .
Xcode (LLVM): thumb-2
__text:00002BA0
__text:00002BA0
__text:00002BA0
__text:00002BA0
__text:00002BA0
__text:00002BA0
__text:00002BA0
__text:00002BA2
__text:00002BA4
__text:00002BA6
__text:00002BAA
__text:00002BAE
__text:00002BB2
__text:00002BB4
__text:00002BB6
__text:00002BB8
__text:00002BBA
__text:00002BBE
__text:00002BC0
__text:00002BC4
__text:00002BC8
__text:00002BCA
__text:00002BCC
__text:00002BCE
__text:00002BD2
__text:00002BD6
__text:00002BD8

_printf_main2
var_1C
var_18
var_C
80
6F
85
41
4F
C0
04
78
06
05
0D
00
4F
8E
01
02
03
CD
01
05
80

B5
46
B0
F2
F0
F2
22
44
23
21
F1
92
F0
E8
21
22
23
F8
F0
B0
BD

D8 20
07 0C
00 00

04 0E
08 09
0A 10

10 90
0A EA

= -0x1C
= -0x18
= -0xC
PUSH
MOV
SUB
MOVW
MOV.W
MOVT.W
MOVS
ADD
MOVS
MOVS
ADD.W
STR
MOV.W
STMIA.W
MOVS
MOVS
MOVS
STR.W
BLX
ADD
POP

{R7,LR}
R7, SP
SP, SP, #0x14
R0, #0x12D8
R12, #7
R0, #0
R2, #4
R0, PC ; char *
R3, #6
R1, #5
LR, SP, #0x1C+var_18
R2, [SP,#0x1C+var_1C]
R9, #8
LR, {R1,R3,R12}
R1, #1
R2, #2
R3, #3
R9, [SP,#0x1C+var_C]
_printf
SP, SP, #0x14
{R7,PC}

,
thumb-.

1.3.4

, x86 ARM,
, , , .
,
, .

1.4

scanf()

scanf().
int main()
{
int x;
printf ("Enter X:\n");
scanf ("%d", &x);
printf ("You entered %d...\n", x);
return 0;
};

, , scanf() -:
. int.

18

1.4. SCANF()

1.4.1

1.

. , , , , . ,
- ,
. ,
, - .
/++ - .
x86 32- (.., 4 ), x86-64 64-
( 8 ). , x86-64
2 .
, (void*), , memcpy(), , 2
void*, , , , , .
, (
(1.7)). scanf() . ,
, , .
/++ . ,
, .

1.4.2

x86

MSVC 2010:
CONST
SEGMENT
$SG3831
DB
Enter X:, 0aH, 00H
ORG $+2
$SG3832
DB
%d, 00H
ORG $+1
$SG3833
DB
You entered %d..., 0aH, 00H
CONST
ENDS
PUBLIC
_main
EXTRN
_scanf:PROC
EXTRN
_printf:PROC
; Function compile flags: /Odtp
_TEXT
SEGMENT
_x$ = -4
; size = 4
_main
PROC
push
ebp
mov
ebp, esp
push
ecx
push
OFFSET $SG3831
call
_printf
add
esp, 4
lea
eax, DWORD PTR _x$[ebp]
push
eax
push
OFFSET $SG3832
call
_scanf
add
esp, 8
mov
ecx, DWORD PTR _x$[ebp]
push
ecx
push
OFFSET $SG3833
call
_printf
add
esp, 8
xor
eax, eax
mov
esp, ebp
pop
ebp
ret
0
_main
ENDP
_TEXT
ENDS

x .
/++ . , . , ,
x86 .
19

1.4. SCANF()
1.
PUSH ECX
ECX. ( POP ECX )
4 x .
x _x$ ( -4) EBP
.
, , EBP EBP+
, .
ESP, .
EBP ESP .
scanf() .
%d x.
x EAX lea eax, DWORD PTR _x$[ebp].
LEA load effective address, (11.5.6).
LEA EAX
EBP _x$.
lea eax, [ebp-4].
, EBP 4 EAX. EAX
scanf().
printf(). , : You entered %d...\n.
: mov ecx, [ebp-4], ECX x,
, .
ECX printf().
Linux GCC 4.4.1:
main

proc near

var_20
var_1C
var_4

= dword ptr -20h


= dword ptr -1Ch
= dword ptr -4

main

push
mov
and
sub
mov
call
mov
lea
mov
mov
call
mov
mov
mov
mov
call
mov
leave
retn
endp

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 20h
[esp+20h+var_20], offset aEnterX ; "Enter X:"
_puts
eax, offset aD ; "%d"
edx, [esp+20h+var_4]
[esp+20h+var_1C], edx
[esp+20h+var_20], eax
___isoc99_scanf
edx, [esp+20h+var_4]
eax, offset aYouEnteredD___ ; "You entered %d...\n"
[esp+20h+var_1C], edx
[esp+20h+var_20], eax
_printf
eax, 0

GCC printf() puts(), , (1.1.2).


MOV.

1.4.3

ARM

Keil + thumb
.text:00000042
.text:00000042
.text:00000042
.text:00000042
.text:00000042 08 B5

scanf_main
var_8

= -8
PUSH

{R3,LR}

20

1.4. SCANF()
.text:00000044
.text:00000046
.text:0000004A
.text:0000004C
.text:0000004E
.text:00000052
.text:00000054
.text:00000056
.text:0000005A
.text:0000005C

1.
A9
06
69
AA
06
00
A9
06
00
08

A0
F0 D3 F8
46
A0
F0 CD F8
99
A0
F0 CB F8
20
BD

ADR
BL
MOV
ADR
BL
LDR
ADR
BL
MOVS
POP

R0, aEnterX
; "Enter X:\n"
__2printf
R1, SP
R0, aD
; "%d"
__0scanf
R1, [SP,#8+var_8]
R0, aYouEnteredD___ ; "You entered %d...\n"
__2printf
R0, #0
{R3,PC}

scanf() , int. int 32 , 4 32- .


x , IDA var_8, ,
, .., SP , .
SP R1, format-, scanf(). ,
LDR, R1,
printf().
ARM- ,
Xcode LLVM, , , .

1.4.4

x86
x ?
, .
, .
_DATA
SEGMENT
COMM
_x:DWORD
$SG2456
DB
Enter X:, 0aH, 00H
ORG $+2
$SG2457
DB
%d, 00H
ORG $+1
$SG2458
DB
You entered %d..., 0aH, 00H
_DATA
ENDS
PUBLIC
_main
EXTRN
_scanf:PROC
EXTRN
_printf:PROC
; Function compile flags: /Odtp
_TEXT
SEGMENT
_main
PROC
push
ebp
mov
ebp, esp
push
OFFSET $SG2456
call
_printf
add
esp, 4
push
OFFSET _x
push
OFFSET $SG2457
call
_scanf
add
esp, 8
mov
eax, DWORD PTR _x
push
eax
push
OFFSET $SG2458
call
_printf
add
esp, 8
xor
eax, eax
pop
ebp
ret
0
_main
ENDP
_TEXT
ENDS

, . x _DATA.
. , . .
, , , ,
main(). ,
.
21

1.4. SCANF()
:

1.

int x=10; // default value

:
_DATA
_x

SEGMENT
DD
0aH

...

0xA DD (dword = 32 ).
.exe- IDA, x
_DATA, .
IDA, .exe , x ,
IDA :
.data:0040FA80
.data:0040FA80
.data:0040FA84
.data:0040FA84
.data:0040FA88
.data:0040FA88
.data:0040FA8C
.data:0040FA8C
.data:0040FA8C
.data:0040FA90
.data:0040FA90
.data:0040FA94

_x

dd ?

dword_40FA84

dd ?

dword_40FA88

dd ?

; LPVOID lpMem
lpMem

dd ?

dword_40FA90

dd ?

dword_40FA94

dd ?

;
;
;
;
;
;

DATA XREF: _main+10


_main+22
DATA XREF: _memset+1E
unknown_libname_1+28
DATA XREF: ___sbh_find_block+5
___sbh_free_block+2BC

;
;
;
;
;

DATA XREF: ___sbh_find_block+B


___sbh_free_block+2CA
DATA XREF: _V6_HeapAlloc+13
__calloc_impl+72
DATA XREF: ___sbh_free_block+2FE

_x ?, . ,
.exe , . .exe . . ,
.
Linux . x ,
_bss. ELF :
; Segment type: Uninitialized
; Segment permissions: Read/Write

- , 10,
_data, :
; Segment type: Pure data
; Segment permissions: Read/Write

ARM: Keil + thumb


.text:00000000
.text:00000000
...
.text:00000000
.text:00000000
.text:00000002
.text:00000004
.text:00000008
.text:0000000A
.text:0000000C
.text:00000010
.text:00000012
.text:00000014
.text:00000016
.text:0000001A
.text:0000001C
...
.text:00000020
.text:0000002A
.text:0000002B
.text:0000002C

; Segment type: Pure code


AREA .text, CODE
main
PUSH
ADR
BL
LDR
ADR
BL
LDR
LDR
ADR
BL
MOVS
POP
aEnterX

off_2C

{R4,LR}
R0, aEnterX
; "Enter X:\n"
__2printf
R1, =x
R0, aD
; "%d"
__0scanf
R0, =x
R1, [R0]
R0, aYouEnteredD___ ; "You entered %d...\n"
__2printf
R0, #0
{R4,PC}

DCB "Enter X:",0xA,0


DCB
0
DCB
0
DCD x

; DATA XREF: main+2

; DATA XREF: main+8

22

1.4. SCANF()
.text:0000002C
.text:00000030
.text:00000033
.text:00000034
.text:00000047
.text:00000047
.text:00000047
...
.data:00000048
.data:00000048
.data:00000048
.data:00000048
.data:00000048
.data:00000048
.data:00000048

1.
; main+10
DCB "%d",0
; DATA XREF: main+A
DCB
0
aYouEnteredD___ DCB "You entered %d...",0xA,0 ; DATA XREF: main+14
DCB 0
; .text
ends
aD

; Segment type: Pure data


AREA .data, DATA
; ORG 0x48
EXPORT x
x
DCD 0xA
; .data

; DATA XREF: main+8


; main+10

ends

, x , , -, ,
(.data). , (.text)
x ? , , . , .
( , embedded-,
), . ,
, . ,
, , , ,
.
, , , x (off_2C) , , . x
- , . LDR thumb- 1020 . ARM-
4095 , , x
, , 46 - , !
: const, Keil .constdata.
, , , .

1.4.5

scanf()

x86
, scanf() . , , scanf()
- , scanf() .
int main()
{
int x;
printf ("Enter X:\n");
if (scanf ("%d", &x)==1)
printf ("You entered %d...\n", x);
else
printf ("What you entered? Huh?\n");
return 0;
};

, scanf()47 .
, , scanf() 1.
, 0 EOF.
46
47

linker
MSDN: scanf, wscanf

23

1.4. SCANF()
1.
scanf() , -
.
, (MSVC 2010):
; Line 8
lea
push
push
call
add
cmp
jne
; Line 9
mov
push
push
call
add
; Line 10
jmp
$LN2@main:
; Line 11
push
call
add
$LN1@main:
; Line 13
xor

eax, DWORD PTR _x$[ebp]


eax
OFFSET $SG3833 ; %d, 00H
_scanf
esp, 8
eax, 1
SHORT $LN2@main
ecx, DWORD PTR _x$[ebp]
ecx
OFFSET $SG3834 ; You entered %d..., 0aH, 00H
_printf
esp, 8
SHORT $LN1@main

OFFSET $SG3836 ; What you entered? Huh?, 0aH, 00H


_printf
esp, 4

eax, eax

,
( scanf()) EAX.
CMP EAX, 1 (CoMPare), , EAX 1.
CMP: JNE. Jump if Not Equal, ,
.
, EAX 1, JNE JNE,
$LN2@main. , CPU printf()
What you entered? Huh?. , ,
printf() : You entered %d... x.
printf(),
JMP, , printf()
XOR EAX, EAX, return 0.
, , -
CMP Jcc, cc condition code. CMP
48 . Jcc
( ).
, , CMP SUB, .
, CMP. 1 1, ,
0, ZF (zero flag), 0.
EAX, ZF , , .
JNE ZF, . ,
JNE JNZ (Jump if Not Zero).
. , CMP SUB , SUB
- . CMP SUB .
GCC 4.4.1 Linux , ,
.
ARM: Keil + thumb
48

. x86-: http://en.wikipedia.org/wiki/FLAGS_register_(computing).

24

1.5.
1.
Listing 1.16: Keil + thumb
var_8

= -8
PUSH
ADR
BL
MOV
ADR
BL
CMP
BEQ
ADR
BL

{R3,LR}
R0, aEnterX
; "Enter X:\n"
__2printf
R1, SP
R0, aD
; "%d"
__0scanf
R0, #1
loc_1E
R0, aWhatYouEntered ; "What you entered? Huh?\n"
__2printf

MOVS
POP

R0, #0
{R3,PC}

LDR
ADR
BL
B

; CODE XREF: main+12


R1, [SP,#8+var_8]
R0, aYouEnteredD___ ; "You entered %d...\n"
__2printf
loc_1A

loc_1A

; CODE XREF: main+26

loc_1E

: CMP BEQ49 .
CMP x86, .
BEQ , , 0, Z 1. JZ x86.
: , , R0 0 .

1.5

, .
?
#include <stdio.h>
int f (int a, int b, int c)
{
return a*b+c;
};
int main()
{
printf ("%d\n", f(1, 2, 3));
return 0;
};

1.5.1

x86

(MSVC 2010 Express):


Listing 1.17: MSVC 2010 Express
_TEXT
SEGMENT
_a$ = 8
_b$ = 12
_c$ = 16
_f
PROC
; File c:\...\1.c
; Line 4
push
ebp
mov
ebp, esp
; Line 5
mov
eax, DWORD PTR _a$[ebp]
49

; size = 4
; size = 4
; size = 4

(PowerPC, ARM) Branch if Equal

25

1.5.
imul
add
; Line 6
pop
ret
_f
ENDP
_main
PROC
; Line 9
push
mov
; Line 10
push
push
push
call
add
push
push
call
add
; Line 11
xor
; Line 12
pop
ret
_main
ENDP

1.

eax, DWORD PTR _b$[ebp]


eax, DWORD PTR _c$[ebp]
ebp
0

ebp
ebp, esp
3
2
1
_f
esp, 12
eax
OFFSET $SG2463 ; %d, 0aH, 00H
_printf
esp, 8

; 0000000cH

eax, eax
ebp
0

, : main() f(int,int,int).
f(), , , : _a$
= 8, , , _a$
EBP, EBP.
- : a EAX. EAX
IMUL _b, EAX 50 .
EAX _c. EAX ,
. EAX
printf().
GCC 4.4.1 IDA:
Listing 1.18: GCC 4.4.1
f

public f
proc near

arg_0
arg_4
arg_8

= dword ptr
= dword ptr
= dword ptr

push
mov
mov
imul
add
pop
retn
endp

main

public main
proc near

var_10
var_C
var_8

= dword ptr -10h


= dword ptr -0Ch
= dword ptr -8
push
mov
and
sub
mov
mov

50

ebp
ebp,
eax,
eax,
eax,
ebp

; CODE XREF: main+20


8
0Ch
10h

esp
[ebp+arg_0]
[ebp+arg_4]
[ebp+arg_8]

; DATA XREF: _start+17

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 10h
; char *
[esp+10h+var_8], 3
[esp+10h+var_C], 2

26

1.5.
mov
call
mov
mov
mov
call
mov
leave
retn
endp

main

1.

[esp+10h+var_10], 1
f
edx, offset aD ; "%d\n"
[esp+10h+var_C], eax
[esp+10h+var_10], edx
_printf
eax, 0

, .

1.5.2

ARM

Keil + ARM
.text:000000A4
.text:000000A8
.text:000000AC
...
.text:000000B0
.text:000000B0
.text:000000B4
.text:000000B8
.text:000000BC
.text:000000C0
.text:000000C4
.text:000000C8
.text:000000CC
.text:000000D0
.text:000000D4
.text:000000D8

00 30 A0 E1
93 21 20 E0
1E FF 2F E1

MOV
MLA
BX

R3, R0
R0, R3, R1, R2
LR

STMFD
MOV
MOV
MOV
BL
MOV
MOV
ADR
BL
MOV
LDMFD

SP!, {R4,LR}
R2, #3
R1, #2
R0, #1
f
R4, R0
R1, R4
R0, aD_0
__2printf
R0, #0
SP!, {R4,PC}

main
10
03
02
01
F7
00
04
5A
E3
00
10

40
20
10
00
FF
40
10
0F
18
00
80

2D
A0
A0
A0
FF
A0
A0
8F
00
A0
BD

E9
E3
E3
E3
EB
E1
E1
E2
EB
E3
E8

; "%d\n"

main() , (f) .
, 4 , ARM 4- (R0-R3).
f, , (R0-R2) .
MLA (Multiply Accumulate) (R3 R1), (R2) (R0), , ,
.
51 (Fused multiplyadd) ,
, x86 , FMA-52 SIMD.
MOV R3, R0, , ( MLA), , , .
BX LR , , thumb ARM . , , ,
f , , ARM thumb. ,
thumb, BX ,
thumb. , ARM.
Keil + ARM
.text:00000098
f
.text:00000098 91 20 20 E0
.text:0000009C 1E FF 2F E1

MLA
BX

R0, R1, R0, R2


LR

f Keil (-O3). MOV MLA


R0, , .
51
52

wikipedia: -
https://en.wikipedia.org/wiki/FMA_instruction_set

27

1.6.
Keil + thumb
.text:0000005E 48 43
.text:00000060 80 18
.text:00000062 70 47

MULS
ADDS
BX

1.

R0, R1
R0, R0, R2
LR

thumb, MLA , , . MULS R0 R1 R1.


(ADDS) R2, R0.

1.6

x86 53 EAX,
(char), EAX AL. , FPU ST(0) . ARM
R0.

, - main() int void?


.. startup- main() :
push
push
push
call
push
call

envp
argv
argc
main
eax
exit

.., :
exit(main(argc,argv,envp));

main() void, ( return),


exit() , EAX main().
, , - , -. , .

, EAX.
(, int), , , . , , , , ,
. , ,
, .
, .
:
struct s
{
int a;
int b;
int c;
};
struct s get_some_values (int a)
{
struct s rt;
rt.a=a+1;
rt.b=a+2;
rt.c=a+3;
53

.: MSDN: Return Values (C++)

28

1.7.

1.

return rt;
};

. . . (MSVC 2010 /Ox):


$T3853 = 8
; size = 4
_a$ = 12
; size = 4
?get_some_values@@YA?AUs@@H@Z PROC
mov
ecx, DWORD PTR _a$[esp-4]
mov
eax, DWORD PTR $T3853[esp-4]
lea
edx, DWORD PTR [ecx+1]
mov
DWORD PTR [eax], edx
lea
edx, DWORD PTR [ecx+2]
add
ecx, 3
mov
DWORD PTR [eax+4], edx
mov
DWORD PTR [eax+8], ecx
ret
0
?get_some_values@@YA?AUs@@H@Z ENDP

; get_some_values

; get_some_values

$T3853.

1.7

( scanf() (1.4)).
, :
void f1 (int x, int y, int *sum, int *product)
{
*sum=x+y;
*product=x*y;
};
void main()
{
int sum, product;
f1(123, 456, &sum, &product);
printf ("sum=%d, product=%d\n", sum, product);
};

:
Listing 1.19: MSVC 2010
CONST
SEGMENT
$SG3863 DB
$SG3864 DB
CONST
ENDS
_TEXT
SEGMENT
_x$ = 8
_y$ = 12
_sum$ = 16
_product$ = 20
f1 PROC
mov
mov
lea
imul
mov
push
mov
mov
mov
pop
ret
f1 ENDP
_product$ = -8
_sum$ = -4
_main
PROC
sub
lea

sum=%d, product=%d, 0aH, 00H


sum=%d, product=%d, 0aH, 00H

;
;
;
;

size
size
size
size

=
=
=
=

4
4
4
4

; f1
ecx, DWORD PTR _y$[esp-4]
eax, DWORD PTR _x$[esp-4]
edx, DWORD PTR [eax+ecx]
eax, ecx
ecx, DWORD PTR _product$[esp-4]
esi
esi, DWORD PTR _sum$[esp]
DWORD PTR [esi], edx
DWORD PTR [ecx], eax
esi
0
; f1
; size = 4
; size = 4
esp, 8
eax, DWORD PTR _product$[esp+8]

29

1.8.
push
lea
push
push
push
call
mov
mov
push
push
push
call

1.

eax
ecx, DWORD PTR _sum$[esp+12]
ecx
456
123
f1
; f1
edx, DWORD PTR _product$[esp+24]
eax, DWORD PTR _sum$[esp+24]
edx
eax
OFFSET $SG3863
_printf

; 000001c8H
; 0000007bH

...

. references ++: (2.3).

1.8

.
void f_signed (int a, int b)
{
if (a>b)
printf ("a>b\n");
if (a==b)
printf ("a==b\n");
if (a<b)
printf ("a<b\n");
};
void f_unsigned (unsigned int a, unsigned int b)
{
if (a>b)
printf ("a>b\n");
if (a==b)
printf ("a==b\n");
if (a<b)
printf ("a<b\n");
};
int main()
{
f_signed(1, 2);
f_unsigned(1, 2);
return 0;
};

1.8.1

x86

x86 + MSVC
f_signed():
Listing 1.20: MSVC
_a$ = 8
; size = 4
_b$ = 12
; size = 4
_f_signed PROC
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR _a$[ebp]
cmp
eax, DWORD PTR _b$[ebp]
jle
SHORT $LN3@f_signed
push
OFFSET $SG737 ; a>b, 0aH, 00H
call
_printf
add
esp, 4
$LN3@f_signed:
mov
ecx, DWORD PTR _a$[ebp]
cmp
ecx, DWORD PTR _b$[ebp]
jne
SHORT $LN2@f_signed

30

1.8.

1.

push
OFFSET $SG739 ; a==b, 0aH, 00H
call
_printf
add
esp, 4
$LN2@f_signed:
mov
edx, DWORD PTR _a$[ebp]
cmp
edx, DWORD PTR _b$[ebp]
jge
SHORT $LN4@f_signed
push
OFFSET $SG741 ; a<b, 0aH, 00H
call
_printf
add
esp, 4
$LN4@f_signed:
pop
ebp
ret
0
_f_signed ENDP

JLE Jump if Less or Equal. ,


, , . ,
, , printf().
JNE: Jump if Not Equal. , . JGE:
Jump if Greater or Equal . ,
, printf() . , , ,
, .
f_unsigned() , , JBE JAE
JLE JGE, :
GCC
GCC 4.4.1 , puts() (1.1.2) printf().
f_unsigned() GCC:
Listing 1.21: GCC
.globl f_unsigned
.type
f_unsigned, @function
f_unsigned:
push
ebp
mov
ebp, esp
sub
esp, 24
mov
eax, DWORD PTR [ebp+8]
cmp
eax, DWORD PTR [ebp+12]
jbe
.L7
mov
DWORD PTR [esp], OFFSET FLAT:.LC0 ; "a>b"
call
puts
.L7:
mov
eax, DWORD PTR [ebp+8]
cmp
eax, DWORD PTR [ebp+12]
jne
.L8
mov
DWORD PTR [esp], OFFSET FLAT:.LC1 ; "a==b"
call
puts
.L8:
mov
eax, DWORD PTR [ebp+8]
cmp
eax, DWORD PTR [ebp+12]
jae
.L10
mov
DWORD PTR [esp], OFFSET FLAT:.LC2 ; "a<b"
call
puts
.L10:
leave
ret

, : JBE Jump if Below or


Equal JAE Jump if Above or Equal. (JA/JAE/JBE/JBE) JG/JGE/JL/JLE ,
.
: (3.3). ,
JG/JL JA/JBE , ,
(signed) (unsigned).
main(), :

31

1.8.

1.
Listing 1.22: main()

main:
push
mov
and
sub
mov
mov
call
mov
mov
call
mov
leave
ret

1.8.2

ebp
ebp, esp
esp, -16
esp, 16
DWORD PTR [esp+4], 2
DWORD PTR [esp], 1
f_signed
DWORD PTR [esp+4], 2
DWORD PTR [esp], 1
f_unsigned
eax, 0

ARM

Keil + ARM
Listing 1.23: Keil + ARM
.text:000000B8
.text:000000B8
.text:000000B8
.text:000000BC
.text:000000C0
.text:000000C4
.text:000000C8
.text:000000CC
.text:000000D0
.text:000000D4
.text:000000D8
.text:000000DC
.text:000000E0
.text:000000E4
.text:000000E8
.text:000000EC
.text:000000EC

EXPORT f_signed
f_signed
70
01
04
00
1A
A1
04
67
9E
04
70
70
19
99

40
40
00
50
0E
18
00
0F
18
00
80
40
0E
18

2D
A0
50
A0
8F
00
55
8F
00
55
BD
BD
8F
00

E9
E1
E1
E1
C2
CB
E1
02
0B
E1
A8
E8
E2
EA

; CODE XREF: main+C


STMFD
SP!, {R4-R6,LR}
MOV
R4, R1
CMP
R0, R4
MOV
R5, R0
ADRGT
R0, aAB
; "a>b\n"
BLGT
__2printf
CMP
R5, R4
ADREQ
R0, aAB_0
; "a==b\n"
BLEQ
__2printf
CMP
R5, R4
LDMGEFD SP!, {R4-R6,PC}
LDMFD
SP!, {R4-R6,LR}
ADR
R0, aAB_1
; "a<b\n"
B
__2printf
; End of function f_signed

ARM .
, .
, ADD ADDAL, AL Always,
, . 4- 32- ARM-
(condition field). B,
, AL condition field, , , .
ADRGT ADR, CMP, , (Greater Than).
BLGT BL (Greater Than). ADRGT R0 a>b\n, BLGT
printf(). , -GT, , R0 ( ) R4 ( ).
ADREQ BLEQ. ADR BL,
. CMP ( printf()
).
LDMGEFD, LDMFD54 ,
(Greater or Equal).
LDMGEFD SP!, {R4-R6,PC} , , >= , . , < ,
LDMFD SP!, {R4-R6,LR}, , R4-R6, LR PC, ,
54

Load Multiple Full Descending

32

1.8.
1.
. printf() a<b\n
. printf() ,
printf() , (1.3.2).
f_unsigned , ADRHI, BLHI, LDMCSFD
(HI = Unsigned higher, CS = Carry Set (greater than or equal)) ,
.
main() :
Listing 1.24: main()
.text:00000128
.text:00000128
.text:00000128
.text:0000012C
.text:00000130
.text:00000134
.text:00000138
.text:0000013C
.text:00000140
.text:00000144
.text:00000148
.text:00000148

EXPORT main
main
10
02
01
DF
02
01
EA
00
10

40
10
00
FF
10
00
FF
00
80

2D
A0
A0
FF
A0
A0
FF
A0
BD

E9
E3
E3
EB
E3
E3
EB
E3
E8

STMFD
MOV
MOV
BL
MOV
MOV
BL
MOV
LDMFD
; End of function main

SP!, {R4,LR}
R1, #2
R0, #1
f_signed
R1, #2
R0, #1
f_unsigned
R0, #0
SP!, {R4,PC}

, ARM .
? ARM RISC- (pipeline)
. , ,
.
, , , , ,
, , .
x86 , CMOVcc, MOV,
, , CMP
.
Keil + thumb
Listing 1.25: Keil + thumb
.text:00000072
.text:00000072
.text:00000074
.text:00000076
.text:00000078
.text:0000007A
.text:0000007C
.text:0000007E
.text:00000082
.text:00000082
.text:00000082
.text:00000084
.text:00000086
.text:00000088
.text:0000008C
.text:0000008C
.text:0000008C
.text:0000008E
.text:00000090
.text:00000092
.text:00000096
.text:00000096
.text:00000096
.text:00000096

f_signed
70
0C
05
A0
02
A4
06

B5
00
00
42
DD
A0
F0 B7 F8

A5
02
A4
06

42
D1
A0
F0 B2 F8

A5
02
A3
06

42
DA
A0
F0 AD F8

PUSH
MOVS
MOVS
CMP
BLE
ADR
BL

; CODE XREF: main+6


{R4-R6,LR}
R4, R1
R5, R0
R0, R4
loc_82
R0, aAB
; "a>b\n"
__2printf

CMP
BNE
ADR
BL

R5, R4
loc_8C
R0, aAB_0
__2printf

CMP
BGE
ADR
BL

R5, R4
locret_96
R0, aAB_1
__2printf

loc_82

; CODE XREF: f_signed+8

loc_8C

; CODE XREF: f_signed+12

locret_96
70 BD

; "a==b\n"

; "a<b\n"

; CODE XREF: f_signed+1C

POP
{R4-R6,PC}
; End of function f_signed

thumb, B (condition code),


, thumb .
BLE Less than or Equal, BNE Not Equal, BGE Greater than or Equal.
33

1.9. SWITCH()/CASE/DEFAULT
1.
f_unsigned , ,
BLS (Unsigned lower or same) BCS (Carry Set (Greater than or equal)).

1.9
1.9.1

switch()/case/default

void f (int a)
{
switch (a)
{
case 0: printf ("zero\n"); break;
case 1: printf ("one\n"); break;
case 2: printf ("two\n"); break;
default: printf ("something unknown\n"); break;
};
};

x86
(MSVC 2010):
Listing 1.26: MSVC 2010
tv64 = -4
_a$ = 8
_f
PROC
push
mov
push
mov
mov
cmp
je
cmp
je
cmp
je
jmp
$LN4@f:
push
call
add
jmp
$LN3@f:
push
call
add
jmp
$LN2@f:
push
call
add
jmp
$LN1@f:
push
call
add
$LN7@f:
mov
pop
ret
_f
ENDP

; size = 4
; size = 4
ebp
ebp, esp
ecx
eax, DWORD PTR _a$[ebp]
DWORD PTR tv64[ebp], eax
DWORD PTR tv64[ebp], 0
SHORT $LN4@f
DWORD PTR tv64[ebp], 1
SHORT $LN3@f
DWORD PTR tv64[ebp], 2
SHORT $LN2@f
SHORT $LN1@f
OFFSET $SG739 ; zero, 0aH, 00H
_printf
esp, 4
SHORT $LN7@f
OFFSET $SG741 ; one, 0aH, 00H
_printf
esp, 4
SHORT $LN7@f
OFFSET $SG743 ; two, 0aH, 00H
_printf
esp, 4
SHORT $LN7@f
OFFSET $SG745 ; something unknown, 0aH, 00H
_printf
esp, 4
esp, ebp
ebp
0

switch()-, ,
:
void f (int a)
{
if (a==0)

34

1.9. SWITCH()/CASE/DEFAULT

1.

printf ("zero\n");
else if (a==1)
printf ("one\n");
else if (a==2)
printf ("two\n");
else
printf ("something unknown\n");
};

, ,
switch(), if()-. , switch()
if().
, , , ,
- (a) v64.
GCC 4.4.1, ,
( -O3).
, MSVC (/Ox): cl 1.c /Fa1.asm /Ox
Listing 1.27: MSVC
_a$ = 8
_f
PROC
mov
sub
je
sub
je
sub
je
mov
jmp
$LN2@f:
mov
jmp
$LN3@f:
mov
jmp
$LN4@f:
mov
jmp
_f
ENDP

; size = 4
eax, DWORD PTR _a$[esp-4]
eax, 0
SHORT $LN4@f
eax, 1
SHORT $LN3@f
eax, 1
SHORT $LN2@f
DWORD PTR _a$[esp-4], OFFSET $SG791 ; something unknown, 0aH, 00H
_printf
DWORD PTR _a$[esp-4], OFFSET $SG789 ; two, 0aH, 00H
_printf
DWORD PTR _a$[esp-4], OFFSET $SG787 ; one, 0aH, 00H
_printf
DWORD PTR _a$[esp-4], OFFSET $SG785 ; zero, 0aH, 00H
_printf

-, .
: EAX 0. , ,
, 0 EAX ? , ZF (
0 0) JE (Jump if Equal JZ Jump if Zero)
$LN4@f, zero. , , - 0,
.
, , printf()
something unknown.
: , , : a, printf() CALL, JMP. .
CALL . CALL .
( , ,
- ESP) :
ESP RA
ESP+4 a
, printf() ,
. , , .
35

1.9. SWITCH()/CASE/DEFAULT
1.
printf(),
f(), printf(). printf() stdout,
RET, RA ,
f(), f().
printf() f() . -
longjmp()55 . , , .
ARM printf() ,
(1.3.2).
ARM: Keil + ARM
.text:0000014C
.text:0000014C
.text:00000150
.text:00000154
.text:00000158
.text:0000015C
.text:00000160
.text:00000164
.text:00000168
.text:0000016C
.text:00000170
.text:00000170
.text:00000170
.text:00000170

f1
00
13
05
01
4B
02
02
4A
4E

00
0E
00
00
0F
00
00
0F
0F

50
8F
00
50
8F
00
50
8F
8F

E3
02
0A
E3
02
0A
E3
12
02

CMP
ADREQ
BEQ
CMP
ADREQ
BEQ
CMP
ADRNE
ADREQ

R0, #0
R0, aZero
; "zero\n"
loc_170
R0, #1
R0, aOne
; "one\n"
loc_170
R0, #2
R0, aSomethingUnkno ; "something unknown\n"
R0, aTwo
; "two\n"

loc_170
78 18 00 EA

; CODE XREF: f1+8


; f1+14
B

__2printf

, , switch()
if()-.
, , ADREQ ((Equal)),
0 = 0, , R0 zero\n.
BEQ loc_170, 0 = 0. ,
, BEQ , ADREQ R0 -
. , BEQ CMP, ADREQ
.
, ARM -S, ,
, . , ADD
ADDS , . CMP
, , , .
. printf() , ,
(1.3.2). printf()- .
= 2 .
CMP R0, #2 = 2 . , ADRNE (Not
Equal) R0 something unknown \n, 0
1 , . 0 = 2, R0
two\n ADREQ.
ARM: Keil + thumb
.text:000000D4
.text:000000D4
.text:000000D6
.text:000000D8
.text:000000DA
.text:000000DC
.text:000000DE
.text:000000E0
.text:000000E2
.text:000000E4
.text:000000E6
55

f1
10
00
05
01
05
02
05
91
04

B5
28
D0
28
D0
28
D0
A0
E0

PUSH
{R4,LR}
CMP
R0, #0
BEQ
zero_case
CMP
R0, #1
BEQ
one_case
CMP
R0, #2
BEQ
two_case
ADR
R0, aSomethingUnkno ; "something unknown\n"
B
default_case
; -------------------------------------------------------------------------

http://en.wikipedia.org/wiki/Setjmp.h

36

1.9. SWITCH()/CASE/DEFAULT
.text:000000E6
.text:000000E6
.text:000000E8
.text:000000EA
.text:000000EA
.text:000000EA
.text:000000EC
.text:000000EE
.text:000000EE
.text:000000EE
.text:000000F0
.text:000000F0
.text:000000F0
.text:000000F4
.text:000000F4

1.
zero_case

95 A0
02 E0

96 A0
00 E0

97 A0

06 F0 7E F8
10 BD

; CODE XREF: f1+4


ADR
R0, aZero
; "zero\n"
B
default_case
; ------------------------------------------------------------------------one_case
; CODE XREF: f1+8
ADR
R0, aOne
; "one\n"
B
default_case
; ------------------------------------------------------------------------two_case
; CODE XREF: f1+C
ADR
R0, aTwo
; "two\n"
default_case
; CODE XREF: f1+10
; f1+14
BL
__2printf
POP
{R4,PC}
; End of function f1

, thumb- ,
thumb- x86, .

1.9.2

,
JE/JNE .
void f (int a)
{
switch (a)
{
case 0: printf ("zero\n"); break;
case 1: printf ("one\n"); break;
case 2: printf ("two\n"); break;
case 3: printf ("three\n"); break;
case 4: printf ("four\n"); break;
default: printf ("something unknown\n"); break;
};
};

x86
(MSVC 2010):
Listing 1.28: MSVC 2010
tv64 = -4
_a$ = 8
_f
PROC
push
mov
push
mov
mov
cmp
ja
mov
jmp
$LN6@f:
push
call
add
jmp
$LN5@f:
push
call
add
jmp
$LN4@f:
push
call
add
jmp
$LN3@f:
push

; size = 4
; size = 4
ebp
ebp, esp
ecx
eax, DWORD PTR _a$[ebp]
DWORD PTR tv64[ebp], eax
DWORD PTR tv64[ebp], 4
SHORT $LN1@f
ecx, DWORD PTR tv64[ebp]
DWORD PTR $LN11@f[ecx*4]
OFFSET $SG739 ; zero, 0aH, 00H
_printf
esp, 4
SHORT $LN9@f
OFFSET $SG741 ; one, 0aH, 00H
_printf
esp, 4
SHORT $LN9@f
OFFSET $SG743 ; two, 0aH, 00H
_printf
esp, 4
SHORT $LN9@f
OFFSET $SG745 ; three, 0aH, 00H

37

1.9. SWITCH()/CASE/DEFAULT

1.

call
_printf
add
esp, 4
jmp
SHORT $LN9@f
$LN2@f:
push
OFFSET $SG747 ; four, 0aH, 00H
call
_printf
add
esp, 4
jmp
SHORT $LN9@f
$LN1@f:
push
OFFSET $SG749 ; something unknown, 0aH, 00H
call
_printf
add
esp, 4
$LN9@f:
mov
esp, ebp
pop
ebp
ret
0
npad
2
$LN11@f:
DD
$LN6@f ; 0
DD
$LN5@f ; 1
DD
$LN4@f ; 2
DD
$LN3@f ; 3
DD
$LN2@f ; 4
_f
ENDP

: printf() . , , , ,
. , $LN11@f.
, a 4, $LN1@f,
printf() something unknown.
a 4, 4 . , , .
, a 2. 2 * 4 = 8 ( 32- , , 4 ). 8 $LN11@f
, $LN4@f. JMP $LN4@f
.
jumptable.
printf() two. , jmp DWORD PTR $LN11@f[ecx*4]
DWORD, $LN11@f + ecx * 4.
npad (3.2) , ,
4 ( 16). 32-
, , -, .
GCC 4.4.1:
Listing 1.29: GCC 4.4.1
f

public f
proc near

var_18
arg_0

= dword ptr -18h


= dword ptr 8

; CODE XREF: main+10

push
mov
sub
cmp
ja
mov
shl
mov
jmp

ebp
ebp, esp
esp, 18h
; char *
[ebp+arg_0], 4
short loc_8048444
eax, [ebp+arg_0]
eax, 2
eax, ds:off_804855C[eax]
eax

mov
call
jmp

; DATA XREF: .rodata:off_804855C


[esp+18h+var_18], offset aZero ; "zero"
_puts
short locret_8048450

mov

; DATA XREF: .rodata:08048560


[esp+18h+var_18], offset aOne ; "one"

loc_80483FE:

loc_804840C:

38

1.9. SWITCH()/CASE/DEFAULT

1.

call
jmp

_puts
short locret_8048450

mov
call
jmp

; DATA XREF: .rodata:08048564


[esp+18h+var_18], offset aTwo ; "two"
_puts
short locret_8048450

mov
call
jmp

; DATA XREF: .rodata:08048568


[esp+18h+var_18], offset aThree ; "three"
_puts
short locret_8048450

mov
call
jmp

; DATA XREF: .rodata:0804856C


[esp+18h+var_18], offset aFour ; "four"
_puts
short locret_8048450

mov
call

; CODE XREF: f+A


[esp+18h+var_18], offset aSomethingUnkno ; "something unknown"
_puts

loc_804841A:

loc_8048428:

loc_8048436:

loc_8048444:

locret_8048450:

; CODE XREF: f+26


; f+34...
leave
retn
endp

f
off_804855C

dd
dd
dd
dd
dd

offset
offset
offset
offset
offset

loc_80483FE
loc_804840C
loc_804841A
loc_8048428
loc_8048436

; DATA XREF: f+12

, : arg_0 4
2 ( 4) (1.15.3).
off_804855C .
ARM: Keil + ARM
00000174
00000174
00000178
0000017C
00000180
00000180
00000180
00000180
00000184
00000184
00000184
00000184
00000188
00000188
00000188
00000188
0000018C
0000018C
0000018C
0000018C
00000190
00000190
00000190
00000190
00000194
00000194
00000194
00000194
00000194
00000198
0000019C
0000019C
0000019C
0000019C

f2
05 00 50 E3
00 F1 8F 30
0E 00 00 EA

CMP
R0, #5
; switch 5 cases
ADDCC
PC, PC, R0,LSL#2 ; switch jump
B
default_case
; jumptable 00000178 default case
; ------------------------------------------------------------------------loc_180

03 00 00 EA

; CODE XREF: f2+4


B
zero_case
; jumptable 00000178 case 0
; ------------------------------------------------------------------------loc_184

04 00 00 EA

; CODE XREF: f2+4


B
one_case
; jumptable 00000178 case 1
; ------------------------------------------------------------------------loc_188

05 00 00 EA

; CODE XREF: f2+4


B
two_case
; jumptable 00000178 case 2
; ------------------------------------------------------------------------loc_18C

06 00 00 EA

; CODE XREF: f2+4


B
three_case
; jumptable 00000178 case 3
; ------------------------------------------------------------------------loc_190

07 00 00 EA

; CODE XREF: f2+4


B
four_case
; jumptable 00000178 case 4
; ------------------------------------------------------------------------zero_case

EC 00 8F E2
06 00 00 EA

; CODE XREF: f2+4


; f2:loc_180
; jumptable 00000178 case 0

ADR
R0, aZero
B
loc_1B8
; ------------------------------------------------------------------------one_case

; CODE XREF: f2+4


; f2:loc_184

39

1.9. SWITCH()/CASE/DEFAULT
0000019C
000001A0
000001A4
000001A4
000001A4
000001A4
000001A4
000001A8
000001AC
000001AC
000001AC
000001AC
000001AC
000001B0
000001B4
000001B4
000001B4
000001B4
000001B4
000001B8
000001B8
000001B8
000001B8
000001BC
000001BC
000001BC
000001BC
000001BC
000001C0
000001C0

EC 00 8F E2
04 00 00 EA

1.

ADR
R0, aOne
; jumptable 00000178 case 1
B
loc_1B8
; ------------------------------------------------------------------------two_case

01 0C 8F E2
02 00 00 EA

; CODE XREF: f2+4


; f2:loc_188
; jumptable 00000178 case 2

ADR
R0, aTwo
B
loc_1B8
; ------------------------------------------------------------------------three_case

01 0C 8F E2
00 00 00 EA

; CODE XREF: f2+4


; f2:loc_18C
; jumptable 00000178 case 3

ADR
R0, aThree
B
loc_1B8
; ------------------------------------------------------------------------four_case

01 0C 8F E2

ADR

; CODE XREF: f2+4


; f2:loc_190
; jumptable 00000178 case 4

R0, aFour

loc_1B8
66 18 00 EA

B
__2printf
; ------------------------------------------------------------------------default_case

D4 00 8F E2
FC FF FF EA

; CODE XREF: f2+24


; f2+2C

ADR
B
; End of function f2

; CODE XREF: f2+4


; f2+8
R0, aSomethingUnkno ; jumptable 00000178 default case
loc_1B8

ARM,
4 .
, , 4, ,
something unknown\n .
CMP R0, #5 c 5.
ADDCC PC, PC, R0,LSL#2 56 0 < 5
(CC=Carry clear / Less than). , ADDCC ( 0 5),
default_case.
0 < 5 ADDCC , :
R0 4. , LSL#2 2
. (1.15.3) , 2
4.
0 * 4 PC, , ,
B (Branch).
ADDCC , PC 8 (0x180) ADDCC (0x178), , , 2 .
ARM: ADDCC,
, PC .
, = 0, PC , PC PC ( 8) loc_180, 8
ADDCC.
, = 1, PC + 8 + * 4 = + 8 + 1 * 4 = + 16 = 0184,
loc_184.
, PC 4. 4
ARM , B, 5 .
B, , ,
switch(). , .
ARM: Keil + thumb
56

ADD

40

1.9. SWITCH()/CASE/DEFAULT
000000F6
000000F6
000000F6
000000F8
000000FA
000000FA
000000FE
000000FF
00000105
00000106
00000106
00000106
00000108
0000010A
0000010A
0000010A
0000010A
0000010C
0000010E
0000010E
0000010E
0000010E
00000110
00000112
00000112
00000112
00000112
00000114
00000116
00000116
00000116
00000116
00000118
00000118
00000118
00000118
0000011C
0000011E
0000011E
0000011E
0000011E
00000120

000061D0
000061D0
000061D0
000061D0
000061D2
000061D2
000061D2
000061D4
000061D4
000061D4
000061D4
000061D4
000061D4
000061D4
000061D8
000061DC
000061E0
000061E4
000061E8
000061E8

1.
EXPORT f2

f2
10 B5
03 00
06 F0 69 F8

PUSH
{R4,LR}
MOVS
R3, R0
BL
__ARM_common_switch8_thumb ; switch 6 cases
; ------------------------------------------------------------------------05
DCB 5
04 06 08 0A 0C 10
DCB 4, 6, 8, 0xA, 0xC, 0x10 ; jump table for switch statement
00
ALIGN 2
zero_case

; CODE XREF: f2+4


ADR
R0, aZero
; jumptable 000000FA case 0
B
loc_118
; -------------------------------------------------------------------------

8D A0
06 E0

one_case

; CODE XREF: f2+4


ADR
R0, aOne
; jumptable 000000FA case 1
B
loc_118
; -------------------------------------------------------------------------

8E A0
04 E0

two_case

; CODE XREF: f2+4


ADR
R0, aTwo
; jumptable 000000FA case 2
B
loc_118
; -------------------------------------------------------------------------

8F A0
02 E0

three_case

; CODE XREF: f2+4


ADR
R0, aThree
; jumptable 000000FA case 3
B
loc_118
; -------------------------------------------------------------------------

90 A0
00 E0

four_case
91 A0

ADR

R0, aFour

loc_118
06 F0 6A F8
10 BD

; CODE XREF: f2+12


; f2+16

BL
__2printf
POP
{R4,PC}
; ------------------------------------------------------------------------default_case

82 A0
FA E7

; CODE XREF: f2+4


; jumptable 000000FA case 4

ADR
B

; CODE XREF: f2+4


R0, aSomethingUnkno ; jumptable 000000FA default case
loc_118

EXPORT __ARM_common_switch8_thumb
__ARM_common_switch8_thumb
; CODE XREF: example6_f2+4
BX
PC
; --------------------------------------------------------------------------ALIGN 4
; End of function __ARM_common_switch8_thumb

78 47
00 00

CODE32
; =============== S U B R O U T I N E =======================================

01
0C
0C
03
83
1C

C0
00
30
30
C0
FF

5E
53
DE
DE
8E
2F

E5
E1
27
37
E0
E1

__32__ARM_common_switch8_thumb
; CODE XREF: __ARM_common_switch8_thumb
LDRB
R12, [LR,#-1]
CMP
R3, R12
LDRCSB R3, [LR,R12]
LDRCCB R3, [LR,R3]
ADD
R12, LR, R3,LSL#1
BX
R12
; End of function __32__ARM_common_switch8_thumb

thumb thumb-2, .
, x86.
, ,
, default-, , , ,
.
,
__ARM_common_switch8_thumb. BX PC , ARM-. .
41

1.10.
1.
, .
, LR . ,
, LR
BL __ARM_common_switch8_thumb, .
, ,
, switch()-
.
IDA , jumptable 000000FA case 0.

1.10

1.10.1

x86

, x86 LOOP,
ECX 0, ECX . ,
, ,
. , - LOOP, , ,
.
, , ,
.
/++ for(), while(), do/while().
for().
, , (/)
.
for (; ; )
{
_;
}

, .
:
int main()
{
int i;
for (i=2; i<10; i++)
f(i);
return 0;
};

(MSVC 2010):
Listing 1.30: MSVC 2010
_i$ = -4
_main
PROC
push
ebp
mov
ebp, esp
push
ecx
mov
DWORD PTR _i$[ebp], 2
jmp
SHORT $LN3@main
$LN2@main:
mov
eax, DWORD PTR _i$[ebp]
add
eax, 1
mov
DWORD PTR _i$[ebp], eax
$LN3@main:
cmp
DWORD PTR _i$[ebp], 10
jge
SHORT $LN1@main
mov
ecx, DWORD PTR _i$[ebp]
push
ecx
call
_f

; :
; 1 i

; **
; i 10,
; : f(i)

42

1.10.

1.

add
esp, 4
jmp
SHORT $LN2@main
$LN1@main:
xor
eax, eax
mov
esp, ebp
pop
ebp
ret
0
_main
ENDP

;
;

, .
GCC 4.4.1 , :
Listing 1.31: GCC 4.4.1
main

proc near

var_20
var_4

= dword ptr -20h


= dword ptr -4

; DATA XREF: _start+17

push
mov
and
sub
mov
jmp

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 20h
[esp+20h+var_4], 2
short loc_8048476

mov
mov
call
add

eax, [esp+20h+var_4]
[esp+20h+var_20], eax
f
[esp+20h+var_4], 1 ; i

cmp
jle
mov
leave
retn
endp

[esp+20h+var_4], 9
short loc_8048465
eax, 0

; i

loc_8048465:

loc_8048476:

main

; i<=9,

, MSVC 2010 (/Ox):


Listing 1.32: MSVC
_main
PROC
push
esi
mov
esi, 2
$LL3@main:
push
esi
call
_f
inc
esi
add
esp, 4
cmp
esi, 10
; 0000000aH
jl
SHORT $LL3@main
xor
eax, eax
pop
esi
ret
0
_main
ENDP

: i ,
: ESI. , .
, , : f()
ESI. , ESI
f(), . :
PUSH ESI/POP ESI .
GCC 4.4.1 (-O3):
Listing 1.33: GCC 4.4.1
main

proc near

var_10

= dword ptr -10h

; DATA XREF: _start+17

43

1.10.

main

1.
push
mov
and
sub
mov
call
mov
call
mov
call
mov
call
mov
call
mov
call
mov
call
mov
call
xor
leave
retn
endp

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 10h
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
[esp+10h+var_10],
f
eax, eax

2
3
4
5
6
7
8
9

, GCC 57 .
, , ,
, . ,
.
OK, i 100 . GCC :
Listing 1.34: GCC
main

public main
proc near

var_20

= dword ptr -20h


push
mov
and
push
mov
sub

ebp
ebp,
esp,
ebx
ebx,
esp,

esp
0FFFFFFF0h
2
1Ch

; i=2

; loc_80484D0 ( ) 16-
nop
loc_80484D0:

main

mov
add
call
cmp
jnz
add
xor
pop
mov
pop
retn
endp

[esp+20h+var_20], ebx ; i f()


ebx, 1
; i++
f
ebx, 64h ; i==100?
short loc_80484D0 ; ,
esp, 1Ch
eax, eax ; 0
ebx
esp, ebp
ebp

MSVC 2010 (/Ox). ,


i EBX. GCC
f(), , ,
main() .
57

loop unwinding

44

1.10.

1.10.2

1.

ARM

Keil + ARM
main
STMFD
SP!, {R4,LR}
MOV
R4, #2
B
loc_368
; --------------------------------------------------------------------------loc_35C

; CODE XREF: main+1C


MOV
BL
ADD

R0, R4
f
R4, R4, #1

CMP
BLT
MOV
LDMFD

R4, #0xA
loc_35C
R0, #0
SP!, {R4,PC}

loc_368

; CODE XREF: main+8

i R4.
MOV R4, #2 i.
MOV R0, R4 BL f ,
f() .
ADD R4, R4, #1 i .
CMP R4, #0xA i 0xA (10). BLT (Branch Less Than) , i 10.
, R0 0 ( 0)
.
Keil + thumb
_main
PUSH
MOVS

{R4,LR}
R4, #2

MOVS
BL
ADDS
CMP
BLT
MOVS
POP

R0, R4
example7_f
R4, R4, #1
R4, #0xA
loc_132
R0, #0
{R4,PC}

loc_132

; CODE XREF: _main+E

, .
Xcode (LLVM) + thumb-2
_main
PUSH
MOVW
MOVS
MOVT.W
ADD
ADD
MOV
BLX
MOV
MOVS
BLX
MOV
MOVS
BLX
MOV
MOVS
BLX

{R4,R7,LR}
R4, #0x1124 ; "%d\n"
R1, #2
R4, #0
R7, SP, #4
R4, PC
R0, R4
_printf
R0, R4
R1, #3
_printf
R0, R4
R1, #4
_printf
R0, R4
R1, #5
_printf

45

1.11. STRLEN()
MOV
MOVS
BLX
MOV
MOVS
BLX
MOV
MOVS
BLX
MOV
MOVS
BLX
MOVS
POP

1.
R0, R4
R1, #6
_printf
R0, R4
R1, #7
_printf
R0, R4
R1, #8
_printf
R0, R4
R1, #9
_printf
R0, #0
{R4,R7,PC}

, f() :
void f(int i)
{
// do something here
printf ("%d\n", i);
};

, LLVM , f()
inline-, 8 . ,
, , .

1.10.3

: i, , i, . .
, . , ,
:
for (i; i<total_entries_to_process; i++)
_;

total_entries_to_process 0, . .
, ,
, ,
Keil, Xcode (LLVM), MSVC GCC .

1.11

strlen()

. , strlen()58 while(). ,
MSVC:
int strlen (const char * str)
{
const char *eos = str;
while( *eos++ ) ;
return( eos - str - 1 );
}

1.11.1

x86

, :
58

46

1.11. STRLEN()

1.

_eos$ = -4
; size
_str$ = 8
; size
_strlen PROC
push
ebp
mov
ebp, esp
push
ecx
mov
eax, DWORD PTR _str$[ebp]
mov
DWORD PTR _eos$[ebp], eax
$LN2@strlen_:
mov
ecx, DWORD PTR _eos$[ebp]

= 4
= 4

; str
; eos
; ecx=eos

; , ecx edx signed-


movsx
edx, BYTE PTR [ecx]
mov
eax, DWORD PTR _eos$[ebp]
add
eax, 1
mov
DWORD PTR _eos$[ebp], eax
test
edx, edx
je
SHORT $LN1@strlen_
jmp
SHORT $LN2@strlen_
$LN1@strlen_:

;
;
;
;
;
;

eax=eos
eax
eax eos
edx==0?
, edx ,

;
mov
eax,
sub
eax,
sub
eax,
mov
esp,
pop
ebp
ret
0
_strlen_ ENDP

DWORD PTR _eos$[ebp]


DWORD PTR _str$[ebp]
1
ebp

: MOVSX (1.11.1) TEST.


: MOVSX (1.11.1) -
, , EDX. EDX 32-. MOVSX (1.11.1) MOV
with Sign-Extent. 8- 31- MOVSX (1.11.1) ,
, , .
.
/++, char . , char, int (int
), 2 ( 0xFE)
int, 0x000000FE, , int, , 254, 2.
2 int 0xFFFFFFFE. 0xFE
char int , ,
. MOVSX (1.11.1).
. (3.3).
, , char
EDX , , DL. : , register allocator
.
TEST EDX, EDX. TEST (1.15).
, EDX 0.
GCC 4.4.1:
strlen

public strlen
proc near

eos
arg_0

= dword ptr -4
= dword ptr 8
push
mov
sub
mov
mov

ebp
ebp, esp
esp, 10h
eax, [ebp+arg_0]
[ebp+eos], eax

mov
movzx
test

eax, [ebp+eos]
eax, byte ptr [eax]
al, al

loc_80483F0:

47

1.11. STRLEN()

strlen

1.
setnz
add
test
jnz
mov
mov
mov
sub
mov
sub
leave
retn
endp

al
[ebp+eos], 1
al, al
short loc_80483F0
edx, [ebp+eos]
eax, [ebp+arg_0]
ecx, edx
ecx, eax
eax, ecx
eax, 1

MSVC, MOVZX MOVSX (1.11.1). MOVZX MOV with Zero-Extent. -


0. , ,
: xor eax, eax / mov al, [...].
, , : mov al, byte ptr
[eax] / test al, al , EAX . , ,
.
, ( ) .
SETNZ. , AL , test al,
al ZF 0, SETNZ, ZF==0 (NZ not zero) 1 AL.
, , , AL , loc_80483F0.
, .
MSVC 2010, (/Ox):
_str$ = 8
; size = 4
_strlen PROC
mov
ecx, DWORD PTR _str$[esp-4] ; ECX ->
mov
eax, ecx
; EAX
$LL2@strlen_:
mov
dl, BYTE PTR [eax]
; DL = *EAX
inc
eax
; EAX++
test
dl, dl
; DL==0?
jne
SHORT $LL2@strlen_
; ,
sub
eax, ecx
;
dec
eax
; EAX
ret
0
_strlen_ ENDP

. ,
.
INC/DEC -, : .
GCC 4.4.1 ( -O3:
strlen

public strlen
proc near

arg_0

= dword ptr

push
mov
mov
mov

ebp
ebp, esp
ecx, [ebp+arg_0]
eax, ecx

movzx
add
test
jnz
not
add
pop
retn
endp

edx, byte ptr [eax]


eax, 1
dl, dl
short loc_8048418
ecx
eax, ecx
ebp

loc_8048418:

strlen

48

1.11. STRLEN()
1.
GCC MSVC MOVZX.
, - MOVZX, mov
dl, byte ptr [eax].
, , GCC char
32- .
NOT. .
XOR ECX, 0ffffffffh. NOT
ADD .
-. ECX, str, .
. : (3.3).
, , , :
ecx=str;
eax=eos;
ecx=(-ecx)-1;
eax=eax+ecx
return eax

. . . :
ecx=str;
eax=eos;
eax=eax-ecx;
eax=eax-1;
return eax

GCC ? . ,
.

1.11.2

ARM

Xcode (LLVM) + ARM


Listing 1.35: Xcode (LLVM) + ARM
_strlen
eos
str

= -8
= -4
SUB
STR
LDR
STR

SP,
R0,
R0,
R0,

SP, #8 ; allocate 8 bytes for local variables


[SP,#8+str]
[SP,#8+str]
[SP,#8+eos]

loc_2CB8

; CODE XREF: _strlen+28


LDR
R0, [SP,#8+eos]
ADD
R1, R0, #1
STR
R1, [SP,#8+eos]
LDRSB
R0, [R0]
CMP
R0, #0
BEQ
loc_2CD4
B
loc_2CB8
; ---------------------------------------------------------------loc_2CD4
LDR
LDR
SUB
SUB
ADD
BX

R0,
R1,
R0,
R0,
SP,
LR

; CODE XREF: _strlen+24


[SP,#8+eos]
[SP,#8+str]
R0, R1 ; R0=eos-str
R0, #1 ; R0=R0-1
SP, #8 ; deallocate 8 bytes for local variables

LLVM , ,
. , , eos str.
, IDA, var_8 var_4 eos str .
49

1.11. STRLEN()
1.
, str eos.
loc_2CB8, .
(LDR, ADD, STR) eos R0,
eos .
LDRSB R0, [R0] (Load Register Signed Byte)
R0, 32- (signed) R0.
MOVSX (1.11.1) x86. (signed), char
. (1.11.1) , x86.
, , ARM 8- 16- , x86. , x86
, 16- 8086 8- 8080, ARM
32- RISC-. , ARM,
, 32- .
, LDRSB R0, . CMP BEQ ,
0. 0, . 0,
.
eos str, R0.
N.B. . , , R0-R3
scratch registers, , , . ,
, . , (BX),
LR.
Xcode (LLVM) + thumb
Listing 1.36: Xcode (LLVM) + thumb
_strlen
MOV

R1, R0

LDRB.W
CMP
BNE
MVNS
ADD
BX

; CODE XREF: _strlen+8


R2, [R1],#1
R2, #0
loc_2DF6
R0, R0
R0, R1
LR

loc_2DF6

LLVM eos str ,


. , str R0,
eos R1.
LDRB.W R2, [R1],#1 R2 R1,
(signed), 32- , . #1 Postindexed addressing, , R1 .
.
x86 , , PDP-11. , -, -, - -
PDP-11, ( PDP-11)
*ptr++, *++ptr, *ptr--, *--ptr. , .
:

50

1.12. 9

-

ARM
post-indexed addressing


*ptr++

post-indexed addressing

*ptr--

pre-indexed addressing

*++ptr

post-indexed addressing

*--ptr

1.

*ptr,
ptr
*ptr,
ptr
ptr,
*ptr
ptr,
*ptr

( ) , , , , (
), PDP-7 [21] [22].
, , , .
CMP BNE59 , ,
0.
MVNS60 ( , NOT x86) ADD 1.
, 0 = + , ,
, , , (1.11.1).
, LLVM, GCC, , .
Keil + ARM
Listing 1.37: Keil + ARM
_strlen
MOV

R1, R0

LDRB
CMP
SUBEQ
SUBEQ
BNE
BX

R2, [R1],#1
R2, #0
R0, R1, R0
R0, R0, #1
loc_2C8
LR

loc_2C8

; CODE XREF: _strlen+14

, 1
, . -EQ, ,
CMP
. , R0 0, SUBEQ R0.

1.12

:
int f(int a)
{
return a/9;
};

1.12.1

x86

. . . :
Listing 1.38: MSVC
_a$ = 8
_f
PROC
59
60

; size = 4

(PowerPC, ARM) Branch if Not Equal


MoVe Not

51

1.12. 9

_f

push
mov
mov
cdq
mov
idiv
pop
ret
ENDP

1.

ebp
ebp, esp
eax, DWORD PTR _a$[ebp]
; EAX EDX:EAX
ecx, 9
ecx
ebp
0

IDIV 64- EDX:EAX ECX. ,


EAX 61 , EDX .
EAX, , ,
. - IDIV EDX:EAX, CDQ EAX
64- , MOVSX (1.11.1).
(/Ox) :
Listing 1.39: MSVC
_a$ = 8
_f
PROC

_f

mov
mov
imul
sar
mov
shr
add
ret
ENDP

; size = 4

ecx,
eax,
ecx
edx,
eax,
eax,
eax,
0

DWORD PTR _a$[esp-4]


954437177
; 38e38e39H
1
edx
31
edx

; 0000001fH

. .
62 . GCC 4.4.1
MSVC :
Listing 1.40: GCC 4.4.1
f

public f
proc near

arg_0

= dword ptr

push
mov
mov
mov
mov
imul
sar
mov
sar
mov
sub
mov
pop
retn
endp

1.12.2

ebp
ebp,
ecx,
edx,
eax,
edx
edx,
eax,
eax,
ecx,
ecx,
eax,
ebp

esp
[ebp+arg_0]
954437177
ecx
1
ecx
1Fh
edx
eax
ecx

ARM

ARM, (pure) RISC- .


32- . ( )63 , : ,
(1.15).
61


[27, 10-3] MSDN: Integer division by constants, http://www.nynaeve.
net/?p=115
63
hack
62

52

1.12. 9
1.
32- 10 [17, 3.3 Division by a Constant].
.
; takes argument in a1
; returns quotient in a1, remainder in a2
; cycles could be saved if only divide or remainder is required
SUB
a2, a1, #10
; keep (x-10) for later
SUB
a1, a1, a1, lsr #2
ADD
a1, a1, a1, lsr #4
ADD
a1, a1, a1, lsr #8
ADD
a1, a1, a1, lsr #16
MOV
a1, a1, lsr #3
ADD
a3, a1, a1, asl #2
SUBS
a2, a2, a3, asl #1
; calc (x-10) - (x/10)*10
ADDPL a1, a1, #1
; fix-up quotient
ADDMI a2, a2, #10
; fix-up remainder
MOV
pc, lr

Xcode (LLVM) + ARM


__text:00002C58
__text:00002C60
__text:00002C64
__text:00002C68
__text:00002C6C

39
10
C0
A0
1E

1E
F1
10
0F
FF

08
50
A0
81
2F

E3 E3 18 43 E3
E7
E1
E0
E1

MOV
SMMUL
MOV
ADD
BX

R1,
R0,
R1,
R0,
LR

0x38E38E39
R0, R1
R0,ASR#1
R1, R0,LSR#31

, MSVC GCC . , LLVM .


, MOV 32- ,
ARM. , , 8
4-, , 2 . 16
0x8E39, , MOVT, 16
0x383E. IDA ,
-.
SMMUL (Signed Most Significant Word Multiply) (signed)
R0 32 , 32 .
MOV R1, R0,ASR#1 .
ADD R0, R1, R0,LSR#31 0 = 1 + 0 >> 31
ARM . ,
(MOV, ADD, SUB, RSB)64 , ,
. ASR Arithmetic Shift Right, LSR Logican Shift Right.
Xcode (LLVM) + thumb-2
MOV
SMMUL.W
ASRS
ADD.W
BX

R1,
R0,
R1,
R0,
LR

0x38E38E39
R0, R1
R0, #1
R1, R0,LSR#31

thumb ,
ASRS ( ).
Xcode (LLVM) Keil
LLVM
___divsi3.
Keil __aeabi_idivmod.
64

data processing instructions

53

1.13. FPU

1.12.3

1.

, :
mov
imul
sar

mov
shr
add

eax, MAGICAL CONSTANT


input value
edx, SHIFTING COEFFICIENT ; 2^x
eax, edx
eax, 31
eax, edx

32- ,
.
:
=

232 2

:
Listing 1.41: MSVC 2012
mov
imul
sar
mov
shr
add

eax, 2021161081
DWORD PTR _a$[esp-4]
edx, 3
eax, edx
eax, 31
eax, edx

; 78787879H

; 0000001fH

:
232 23
2021161081
32-, Wolfram Mathematica :
=

In[1]:=N[2^32*2^3/2021161081]
Out[1]:=17.

17.

1.13

FPU

FPU65 .
.
CPU.
FPU 66 ,
Forth67 .
, ( 80486) ,
, . .
80486, FPU .
FPU 80- , IEEE 75468 .
/++ , float (
69 , 32 ) 70 double ( 71 , 64 ).
65

Floating-point unit
http://en.wikipedia.org/wiki/Stack_machine
67
http://en.wikipedia.org/wiki/Forth_(programming_language)
68
http://en.wikipedia.org/wiki/IEEE_754-2008
69
http://en.wikipedia.org/wiki/Single-precision_floating-point_format
70
float- float (1.16.6).
71
http://en.wikipedia.org/wiki/Double-precision_floating-point_format
66

54

1.13. FPU
1.
72
GCC long double (extended precision , 80 ), MSVC .
float int 32- , , , .
, 73 .
, float double , .
float double, ST(0) , FPU-.

1.13.1

:
double f (double a, double b)
{
return a/3.14 + b*4.1;
};

x86
MSVC 2010:
Listing 1.42: MSVC 2010
CONST
SEGMENT
__real@4010666666666666 DQ 04010666666666666r
CONST
ENDS
CONST
SEGMENT
__real@40091eb851eb851f DQ 040091eb851eb851fr
CONST
ENDS
_TEXT
SEGMENT
_a$ = 8
; size = 8
_b$ = 16
; size = 8
_f PROC
push
ebp
mov
ebp, esp
fld
QWORD PTR _a$[ebp]

; 4.1

; 3.14

; : ST(0) = _a
fdiv

QWORD PTR __real@40091eb851eb851f

; : ST(0) = _a 3.13
fld

QWORD PTR _b$[ebp]

; : ST(0) = _b; ST(1) = _a 3.13


fmul

QWORD PTR __real@4010666666666666

; : ST(0) = _b * 4.1; ST(1) = _a 3.13


faddp

ST(1), ST(0)

; : ST(0) =

_f

pop
ret
ENDP

ebp
0

FLD 8 ST(0),
80- (extended precision).
FDIV ST(0) __real@40091eb851eb851f
3.14. ,
, 3.14 IEEE 754.
FDIV, ST(0) 74 .
72

http://en.wikipedia.org/wiki/Extended_precision
significand fraction
74

73

55

1.13. FPU
1.
, FDIVP, ST(1) ST(0),
. Forth75 , 76 .
FLD b.
, ST(1) , ST(0) b.
FMUL b ST(0) __real@4010666666666666
4.1, ST(0).
FADDP , ST(1) ST(0),
ST(0).
ST(0), , .
GCC 4.4.1 ( -O3) , :
Listing 1.43: GCC 4.4.1
f

public f
proc near

arg_0
arg_8

= qword ptr
= qword ptr
push
fld

8
10h

ebp
ds:dbl_8048608 ; 3.14

; : ST(0) = 3.13
mov
fdivr

ebp, esp
[ebp+arg_0]

; : ST(0) =
fld

ds:dbl_8048610 ; 4.1

; : ST(0) = 4.1, ST(1) =


fmul

[ebp+arg_8]

; : ST(0) = , ST(1) =
pop
faddp

ebp
st(1), st

; : ST(0) =
retn
endp

, 3.14 ( ST(0)), arg_0


ST(0).
FDIVR Reverse Divide . , ( ), FMUL -R .
FADDP , . ,
ST(0) .
IDA, ST(0)
ST.
ARM: Xcode (LLVM) + ARM
ARM , . , VFP
(Vector Floating Point).
75
76

http://en.wikipedia.org/wiki/Forth_(programming_language)
http://en.wikipedia.org/wiki/Stack_machine

56

1.13. FPU
1.
x86 , FPU-, ,
.
f
VLDR
VMOV
VMOV
VDIV.F64
VLDR
VMUL.F64
VADD.F64
VMOV
BX
dbl_2C98
dbl_2CA0

D16, =3.14
D17, R0, R1 ;
D18, R2, R3 ;
D16, D17, D16
D17, =4.1
D17, D18, D17
D16, D17, D16
R0, R1, D16
LR

DCFD 3.14
DCFD 4.1

load a
load b
; a/3.14
; b*4.1
; +

; DATA XREF: f
; DATA XREF: f+10

, , D. 64- , 32,
(double) SIMD ( ARM
NEON).
32 32- S-,
(float).
: D- double-, S-
single-.
(3.14 4.1) IEEE 754.
VLDR VMOV , , LDR MOV,
D-. , , D-,
, SIMD (NEON),
.
, R-, ,
64 , R-.
VMOV D17, R0, R1 32- R0 R1 64 D17.
VMOV R0, R1, D16 , D16
R0 R1, , , 64 , R0
R1.
VDIV, VMUL VADD, , , , , , 77 , 78 79 .
thumb-2 .
ARM: Keil + thumb
f
PUSH
MOVS
MOVS
MOVS
MOVS
LDR
LDR
MOVS
MOVS
BL
MOVS
MOVS
LDR
LDR
MOVS
MOVS
BL

{R3-R7,LR}
R7, R2
R4, R3
R5, R0
R6, R1
R2, =0x66666666
R3, =0x40106666
R0, R7
R1, R4
__aeabi_dmul
R7, R0
R4, R1
R2, =0x51EB851F
R3, =0x40091EB8
R0, R5
R1, R6
__aeabi_ddiv

77



79

78

57

1.13. FPU

1.

MOVS
MOVS
BL
POP
dword_364
dword_368
dword_36C
dword_370

DCD
DCD
DCD
DCD

R2, R7
R3, R4
__aeabi_dadd
{R3-R7,PC}

0x66666666
0x40106666
0x51EB851F
0x40091EB8

;
;
;
;

DATA
DATA
DATA
DATA

XREF:
XREF:
XREF:
XREF:

f+A
f+C
f+1A
f+1C

Keil , FPU NEON.


R-, FPU- __aeabi_dmul, __aeabi_ddiv, __aeabi_dadd , , . , FPU-,
.
,
x86, , .
FPU- ARM soft float armel, FPU-
hard float armhf.
Linux, , Raspberry Pi . soft float, R-, hard float, D-.
, , , armhf- armel- , ,
Linux
.

1.13.2

int main ()
{
printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
return 0;
}

x86
(MSVC 2010):
Listing 1.44: MSVC 2010
CONST
SEGMENT
__real@40400147ae147ae1 DQ 040400147ae147ae1r
__real@3ff8a3d70a3d70a4 DQ 03ff8a3d70a3d70a4r
CONST
ENDS
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 8 ;
fld
QWORD PTR
fstp
QWORD PTR
sub
esp, 8 ;
fld
QWORD PTR
fstp
QWORD PTR
call
_pow
add
esp, 8 ;

; 32.01
; 1.54


__real@3ff8a3d70a3d70a4
[esp]

__real@40400147ae147ae1
[esp]
"" .

; 8 .
; ST(0)
fstp
push
call
add
xor
pop

QWORD PTR [esp] ; ST(0) printf()


OFFSET $SG2651
_printf
esp, 12
eax, eax
ebp

58

1.13. FPU
ret
_main

1.

0
ENDP

FLD FSTP / FPU-. pow()80 FPU- ST(0). printf() 8


double.
ARM + Xcode (LLVM) + thumb-2
_main
var_C

= -0xC
PUSH
MOV
SUB
VLDR
VMOV
VLDR
VMOV
BLX
VMOV
MOV
ADD
VMOV
BLX
MOVS
STR
MOV
ADD
POP

dbl_2F90
dbl_2F98

{R7,LR}
R7, SP
SP, SP, #4
D16, =32.01
R0, R1, D16
D16, =1.54
R2, R3, D16
_pow
D16, R0, R1
R0, 0xFC1 ; "32.01 ^ 1.54 = %lf\n"
R0, PC
R1, R2, D16
_printf
R1, 0
R0, [SP,#0xC+var_C]
R0, R1
SP, SP, #4
{R7,PC}

DCFD 32.01
DCFD 1.54

; DATA XREF: _main+6


; DATA XREF: _main+E

, 64- R-.
( ), ,
R- D-.
, _pow R0 R1, R2 R3.
R0 R1. _pow D16, R1 R2,
printf() .
ARM + Keil + ARM
_main
STMFD
LDR
LDR
LDR
LDR
BL
MOV
MOV
MOV
ADR
BL
MOV
LDMFD
y
dword_520
; double x
x
dword_528
a32_011_54Lf

SP!, {R4-R6,LR}
R2, =0xA3D70A4 ; y
R3, =0x3FF8A3D7
R0, =0xAE147AE1 ; x
R1, =0x40400147
pow
R4, R0
R2, R4
R3, R1
R0, a32_011_54Lf ; "32.01 ^ 1.54 = %lf\n"
__2printf
R0, #0
SP!, {R4-R6,PC}

DCD 0xA3D70A4
DCD 0x3FF8A3D7

; DATA XREF: _main+4


; DATA XREF: _main+8

DCD 0xAE147AE1
; DATA XREF: _main+C
DCD 0x40400147
; DATA XREF: _main+10
DCB "32.01 ^ 1.54 = %lf",0xA,0
; DATA XREF: _main+24

D-, R-.
80

59

1.13. FPU

1.13.3

1.

:
double d_max (double a, double b)
{
if (a>b)
return a;
return b;
};

x86
, .
MSVC 2010:
Listing 1.45: MSVC 2010
PUBLIC
_d_max
_TEXT
SEGMENT
_a$ = 8
; size = 8
_b$ = 16
; size = 8
_d_max
PROC
push
ebp
mov
ebp, esp
fld
QWORD PTR _b$[ebp]
; : ST(0) = _b
; _b ( ST(0)) _a,
fcomp

QWORD PTR _a$[ebp]

;
fnstsw ax
test
ah, 5
jp
SHORT $LN1@d_max
; if a>b
fld
QWORD PTR _a$[ebp]
jmp
SHORT $LN2@d_max
$LN1@d_max:
fld
QWORD PTR _b$[ebp]
$LN2@d_max:
pop
ebp
ret
0
_d_max
ENDP

, FLD _b ST(0).
FCOMP ST(0) _a C3/C2/C0
FPU. 16- FPU.
, C3/C2/C0 , , , Intel P6 81 , . , ( FPU
- ). Intel P6 FCOMI/FCOMIP/FUCOMI/FUCOMIP
, ZF/PF/CF.
, FCOMP . FCOM,
, .
FNSTSW AX. C3/C2/C0 , , 14, 10, 8, AX,
AH.
b>a , C3/C2/C0 : 0, 0, 0.
a>b, : 0, 0, 1.
81

Intel P6 Pentium Pro, Pentium II,

60

1.13. FPU
a=b, : 1, 0, 0.

1.

test ah, 5, C3 C1 , 0 2 ( AH)


C0 C2.
parity flag82 . :

One common reason to test the parity flag actually has nothing to do with parity. The FPU
has four condition flags (C0 to C3), but they can not be tested directly, and must instead be first
copied to the flags register. When this happens, C0 is placed in the carry flag, C2 in the parity
flag and C3 in the zero flag. The C2 flag is set when e.g. incomparable floating point values
(NaN or unsupported format) are compared with the FUCOM instructions.83

1 . 0
.
, , PF 1, C0 C2 1 0.
JP (jump if PF==1). C3/C2/C0
, , JP : b>a
a==b ( C3 test ah, 5).
. , FLD _b ST(0),
, _a .
!
MSVC 2010 /Ox
Listing 1.46: MSVC 2010
_a$ = 8
_b$ = 16
_d_max
fld
fld

; size = 8
; size = 8
PROC
QWORD PTR _b$[esp-4]
QWORD PTR _a$[esp-4]

; : ST(0) = _a, ST(1) = _b


fcom
fnstsw
test
jne

ST(1) ; _a ST(1) = (_b)


ax
ah, 65
; 00000041H
SHORT $LN5@d_max

; ST(0) ST(1) ,
; _a
fstp
ST(1)
; : ST(0) = _a
ret
0
$LN5@d_max:
; ST(0) ST(0) ,
; _b
fstp
ST(0)
; : ST(0) = _b
ret
_d_max

0
ENDP

FCOM FCOMP .
, .
C3/C2/C0 :
82

61

1.13. FPU
1.
a>b , C3/C2/C0 : 0, 0, 0.
b>a, : 0, 0, 1.
a=b, : 1, 0, 0.
test ah, 65 C3 C0. ,
a>b: JNE . FSTP ST(1)
ST(0) . ,
ST(0) ( _a) ST(1). _a.
. ST(0) _a .
JNE : b>a a==b. ST(0) ST(0),
,
ST(1) ( , _b). .
FPU .
.
GCC 4.4.1
Listing 1.47: GCC 4.4.1
d_max proc near
b
a
a_first_half
a_second_half
b_first_half
b_second_half
push
mov
sub

=
=
=
=
=
=

qword
qword
dword
dword
dword
dword

ptr -10h
ptr -8
ptr 8
ptr 0Ch
ptr 10h
ptr 14h

ebp
ebp, esp
esp, 10h

; a b :
mov
mov
mov
mov
mov
mov
mov
mov

eax, [ebp+a_first_half]
dword ptr [ebp+a], eax
eax, [ebp+a_second_half]
dword ptr [ebp+a+4], eax
eax, [ebp+b_first_half]
dword ptr [ebp+b], eax
eax, [ebp+b_second_half]
dword ptr [ebp+b+4], eax

; a b FPU
fld
fld

[ebp+a]
[ebp+b]

; : ST(0) - b; ST(1) - a
fxch

st(1) ; ST(1) ST(0)

; : ST(0) - a; ST(1) - b
fucompp
fnstsw
sahf
setnbe
test
jz
fld
jmp

; a b , .., a b
; FPU AX
; SF, ZF, AF, PF, CF AH
al ; AL CF=0 ZF=0
al, al
; AL==0 ?
short loc_8048453 ;
[ebp+a]
short locret_8048456
ax

loc_8048453:
fld
[ebp+b]
locret_8048456:

62

1.13. FPU

1.

leave
retn
d_max endp

FUCOMPP FCOM, ,
-.
-:
FPU ,
NaN84 . , , .
. ,
- , .
, FCOM - . FUCOM
.
SAHF FPU. 8 AH
8 : SF:ZF:-:AF:-:PF::CF <- AH.
, FNSTSW C3/C2/C0 AH,
6, 2, 0 AH.
, fnstsw ax / sahf C3/C2/C0 ZF, PF,
CF.
, C3/C2/C0 :
a b , C3/C2/C0 : 0, 0, 0.
a b, : 0, 0, 1.
a=b, : 1, 0, 0.
, FUCOMPP/FNSTSW/SAHF, :
a>b , : ZF=0, PF=0, CF=0.
a<b, : ZF=0, PF=0, CF=1.
a=b, : ZF=1, PF=0, CF=0.
SETNBE AL , .
JNBE, , SETcc85 1 0 AL, Jcc
. SETNBE 1 CF=0 ZF=0. , 0 AL.
CF 0 ZF 0 : a>b.
AL , JZ ,
_a. , _b.
.
GCC 4.4.1 -O3
Listing 1.48: GCC 4.4.1
d_max

public d_max
proc near

arg_0
arg_8

= qword ptr
= qword ptr
push
mov
fld
fld

84
85

8
10h

ebp
ebp, esp
[ebp+arg_0] ; _a
[ebp+arg_8] ; _b

http://ru.wikipedia.org/wiki/NaN
cc condition code

63

1.13. FPU

1.

; : ST(0) = _b, ST(1) = _a


fxch
st(1)
; : ST(0) = _a, ST(1) = _b
fucom
st(1) ; _a _b
fnstsw ax
sahf
ja
short loc_8048448
; ST(0) ST(0) ( ), , _b
fstp
st
jmp
short loc_804844A
loc_8048448:
; _a ST(0), , _a
fstp
st(1)
loc_804844A:

d_max

pop
retn
endp

ebp

, : JA SAHF. , , , (JA,
JAE, JBE, JBE, JE/JZ, JNA, JNAE, JNB, JNBE, JNE/JNZ) CF ZF. C3/C2/C0
,
. JA CF ZF .
,
FNSTSW/SAHF.
FPU C3/C2/C0 , .
ARM + Xcode (LLVM) + ARM
Listing 1.49: Xcode (LLVM) + ARM
VMOV
VMOV
VCMPE.F64
VMRS
VMOVGT.F64
VMOV
BX

D16, R2, R3 ; b
D17, R0, R1 ; a
D17, D16
APSR_nzcv, FPSCR
D16, D17 ; copy b to D16
R0, R1, D16
LR

. D17 D16 VCMPE. x86, ARM


, (FPSCR), .
x86, ARM ,
, VMRS , 4 (N, Z, C, V)
( APSR).
VMOVGT MOVGT, ,
(GT Greater Than).
, D16 , D17.
, D16 .
VMOV D16 R0
R1.
ARM + Xcode (LLVM) + thumb-2
Listing 1.50: Xcode (LLVM) + thumb-2
VMOV
VMOV
VCMPE.F64

D16, R2, R3 ; b
D17, R0, R1 ; a
D17, D16

64

1.13. FPU
VMRS
IT GT
VMOVGT.F64
VMOV
BX

1.

APSR_nzcv, FPSCR
D16, D17
R0, R1, D16
LR

, . ,
ARM , , .
thumb . 16- 4 ,
.
thumb-2 thumb- .
, IDA, VMOVGT,
.
, VMOV, IDA -GT ,
IT GT.
IT if-then block. ,
, . , IT GT ,
, GT (Greater Than) .
, , Angry Birds ( iOS):
Listing 1.51: Angry Birds Classic
ITE NE
VMOVNE
VMOVEQ

R2, R3, D16


R2, R3, D17

ITE if-then-else .
, ITE (NE, not equal) ,
. ( NE EQ (equal)).
, Angry Birds:
Listing 1.52: Angry Birds Classic
ITTTT EQ
MOVEQ
ADDEQ
POPEQ.W
POPEQ

R0, R4
SP, SP, #0x20
{R8,R10}
{R4-R7,PC}

4 T 4 . IDA -EQ.
, , ITEEE EQ (if-then-else-else-else), :
-EQ
-NE
-NE
-NE

Angry Birds:
Listing 1.53: Angry Birds Classic
CMP.W
ITTE LE
SUBLE.W
NEGLE
MOVGT

R0, #0xFFFFFFFF
R10, R0, #1
R0, R0
R10, R0

ITTE (if-then-then-else) , LE (Less or


Equal) , (GT Greater Than).
. , Angry
Birds ( classic iOS) IT: IT, ITE, ITT, ITTE, ITTT,
ITTTT. ? IDA , ,
4 . , 16- IT
0xBF, grep :
65

1.13. FPU

1.

cat AngryBirdsClassic.lst | grep " BF" | grep "IT" > results.lst

, thumb-2 ,
, IT ,
.
ARM + Xcode (LLVM) + ARM
Listing 1.54: Xcode (LLVM) + ARM
b
a
val_to_return
saved_R7

=
=
=
=

-0x20
-0x18
-0x10
-4

STR
MOV
SUB
BIC
VMOV
VMOV
VSTR
VSTR
VLDR
VLDR
VCMPE.F64
VMRS
BLE
VLDR
VSTR
B

R7, [SP,#saved_R7]!
R7, SP
SP, SP, #0x1C
SP, SP, #7
D16, R2, R3
D17, R0, R1
D17, [SP,#0x20+a]
D16, [SP,#0x20+b]
D16, [SP,#0x20+a]
D17, [SP,#0x20+b]
D16, D17
APSR_nzcv, FPSCR
loc_2E08
D16, [SP,#0x20+a]
D16, [SP,#0x20+val_to_return]
loc_2E10

VLDR
VSTR

D16, [SP,#0x20+b]
D16, [SP,#0x20+val_to_return]

VLDR
VMOV
MOV
LDR
BX

D16, [SP,#0x20+val_to_return]
R0, R1, D16
SP, R7
R7, [SP+0x20+b],#4
LR

loc_2E08

loc_2E10

, - , , .
ARM + Keil + thumb
Listing 1.55: Keil + thumb
PUSH
MOVS
MOVS
MOVS
MOVS
BL
BCS
MOVS
MOVS
POP

{R3-R7,LR}
R4, R2
R5, R3
R6, R0
R7, R1
__aeabi_cdrcmple
loc_1C0
R0, R6
R1, R7
{R3-R7,PC}

MOVS
MOVS
POP

R0, R4
R1, R5
{R3-R7,PC}

loc_1C0

Keil ,
, .
__aeabi_cdrcmple. N.B.
66

1.14.
1.
, BCS (Carry set - Greater than or equal)
.

1.14

, ,
86 ..

1.14.1

#include <stdio.h>
int main()
{
int a[20];
int i;
for (i=0; i<20; i++)
a[i]=i*2;
for (i=0; i<20; i++)
printf ("a[%d]=%d\n", i, a[i]);
return 0;
};

x86
:
Listing 1.56: MSVC
_TEXT
SEGMENT
_i$ = -84
; size = 4
_a$ = -80
; size = 80
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 84
; 00000054H
mov
DWORD PTR _i$[ebp], 0
jmp
SHORT $LN6@main
$LN5@main:
mov
eax, DWORD PTR _i$[ebp]
add
eax, 1
mov
DWORD PTR _i$[ebp], eax
$LN6@main:
cmp
DWORD PTR _i$[ebp], 20
; 00000014H
jge
SHORT $LN4@main
mov
ecx, DWORD PTR _i$[ebp]
shl
ecx, 1
mov
edx, DWORD PTR _i$[ebp]
mov
DWORD PTR _a$[ebp+edx*4], ecx
jmp
SHORT $LN5@main
$LN4@main:
mov
DWORD PTR _i$[ebp], 0
jmp
SHORT $LN3@main
$LN2@main:
mov
eax, DWORD PTR _i$[ebp]
add
eax, 1
mov
DWORD PTR _i$[ebp], eax
$LN3@main:
cmp
DWORD PTR _i$[ebp], 20
; 00000014H
jge
SHORT $LN1@main
mov
ecx, DWORD PTR _i$[ebp]
mov
edx, DWORD PTR _a$[ebp+ecx*4]
push
edx
mov
eax, DWORD PTR _i$[ebp]
86

AKA87

67

1.14.
push
push
call
add
jmp
$LN1@main:
xor
mov
pop
ret
_main

1.

eax
OFFSET $SG2463
_printf
esp, 12
; 0000000cH
SHORT $LN2@main
eax, eax
esp, ebp
ebp
0
ENDP

, , , , .
shl ecx, 1 ECX 2, (1.15.3).
80 , 20 4 .
GCC 4.4.1:
Listing 1.57: GCC 4.4.1
main

public main
proc near

var_70
var_6C
var_68
i_2
i

=
=
=
=
=

dword
dword
dword
dword
dword

ptr
ptr
ptr
ptr
ptr

; DATA XREF: _start+17


-70h
-6Ch
-68h
-54h
-4

push
mov
and
sub
mov
jmp

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 70h
[esp+70h+i], 0
short loc_804840A

mov
mov
add
mov
add

eax, [esp+70h+i]
edx, [esp+70h+i]
edx, edx
; edx=i*2
[esp+eax*4+70h+i_2], edx
[esp+70h+i], 1
; i++

cmp
jle
mov
jmp

[esp+70h+i], 13h
short loc_80483F7
[esp+70h+i], 0
short loc_8048441

mov
mov
mov
mov
mov
mov
mov
call
add

eax, [esp+70h+i]
edx, [esp+eax*4+70h+i_2]
eax, offset aADD ; "a[%d]=%d\n"
[esp+70h+var_68], edx
edx, [esp+70h+i]
[esp+70h+var_6C], edx
[esp+70h+var_70], eax
_printf
[esp+70h+i], 1

cmp
jle
mov
leave
retn
endp

[esp+70h+i], 13h
short loc_804841B
eax, 0

; i=0

loc_80483F7:

loc_804840A:

loc_804841B:

loc_8048441:

main

, a int* ( , int) ,
( ). a[idx], idx
, , .

68

1.14.
1.
: string , const
char*. c. : string[i]
/++!
ARM + Keil + ARM
EXPORT _main
_main
STMFD
SUB

SP!, {R4,LR}
SP, SP, #0x50

MOV
B

R4, #0
loc_4A0

; i

MOV
STR
ADD

R0, R4,LSL#1
R0, [SP,R4,LSL#2]
R4, R4, #1

; R0=R4*2
; store R0 to SP+R4<<2 (same as SP+R4*4)
; i=i+1

CMP
BLT

R4, #20
loc_494

; i<20?
; yes, run loop body again

MOV
B

R4, #0
loc_4C4

; i

LDR
MOV
ADR
BL
ADD

R2, [SP,R4,LSL#2]
R1, R4
R0, aADD
__2printf
R4, R4, #1

; (second printf argument) R2=*(SP+R4<<4) (same as *(SP+R4*4))


; (first printf argument) R1=i
; "a[%d]=%d\n"

CMP
BLT
MOV
ADD
LDMFD

R4, #20
loc_4B0
R0, #0
SP, SP, #0x50
SP!, {R4,PC}

;
;
;
;

; allocate place for 20 int variables

; first loop

loc_494

loc_4A0

; second loop

loc_4B0

; i=i+1

loc_4C4
i<20?
yes, run loop body again
value to return
deallocate place for 20 int variables

int 32 , 4 , 20 int,
80 (0x50) , SUB SP, SP, #0x50
.
, R4.
, , *2, 1 ,
MOV R0, R4,LSL#1 .
STR R0, [SP,R4,LSL#2] R0 .
: SP , R4 . 2 , 4 ( 4 )
.
LDR R2, [SP,R4,LSL#2],
, .
ARM + Keil + thumb
_main
PUSH
SUB

{R4,R5,LR}
SP, SP, #0x54

; allocate place for 20 int variables + one more variable

MOVS
MOV

R0, #0
R5, SP

; i
; pointer to first array element

; first loop

loc_1CE

69

1.14.

1.
LSLS
LSLS
ADDS
CMP
STR
BLT

R1, R0, #1
R2, R0, #2
R0, R0, #1
R0, #20
R1, [R5,R2]
loc_1CE

;
;
;
;
;
;

R1=i<<1 (same as i*2)


R2=i<<2 (same as i*4)
i=i+1
i<20?
store R1 to *(R5+R2) (same R5+i*4)
yes, i<20, run loop body again

MOVS

R4, #0

; i=0

LSLS
LDR
MOVS
ADR
BL
ADDS
CMP
BLT
MOVS
ADD
POP

R0, R4, #2
R2, [R5,R0]
R1, R4
R0, aADD
__2printf
R4, R4, #1
R4, #20
loc_1DC
R0, #0
SP, SP, #0x54
{R4,R5,PC}

; R0=i<<2 (same as i*4)


; load from *(R5+R0) (same as R5+i*4)

; second loop

loc_1DC

; "a[%d]=%d\n"
;
;
;
;
;

i=i+1
i<20?
yes, i<20, run loop body again
value to return
deallocate place for 20 int variables + one more variable

thumb . thumb ( LSLS),


.
- , 4
.

1.14.2

, []. , printf() , ?
? /++, , , .
:
#include <stdio.h>
int main()
{
int a[20];
int i;
for (i=0; i<20; i++)
a[i]=i*2;
printf ("a[100]=%d\n", a[100]);
return 0;
};

(MSVC 2010):
_TEXT
SEGMENT
_i$ = -84
; size = 4
_a$ = -80
; size = 80
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 84
; 00000054H
mov
DWORD PTR _i$[ebp], 0
jmp
SHORT $LN3@main
$LN2@main:
mov
eax, DWORD PTR _i$[ebp]
add
eax, 1
mov
DWORD PTR _i$[ebp], eax
$LN3@main:
cmp
DWORD PTR _i$[ebp], 20 ; 00000014H
jge
SHORT $LN1@main
mov
ecx, DWORD PTR _i$[ebp]
shl
ecx, 1
mov
edx, DWORD PTR _i$[ebp]
mov
DWORD PTR _a$[ebp+edx*4], ecx

70

1.14.
jmp
$LN1@main:
mov
push
push
call
add
xor
mov
pop
ret
_main

1.

SHORT $LN2@main
eax, DWORD PTR _a$[ebp+400]
eax
OFFSET $SG2460
_printf
esp, 8
eax, eax
esp, ebp
ebp
0
ENDP

:
a[100]=760826203

-, , 400
.
, ? - ,
,
88 , .
, - , ?
:
#include <stdio.h>
int main()
{
int a[20];
int i;
for (i=0; i<30; i++)
a[i]=i;
return 0;
};

:
_TEXT
SEGMENT
_i$ = -84
; size = 4
_a$ = -80
; size = 80
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 84
; 00000054H
mov
DWORD PTR _i$[ebp], 0
jmp
SHORT $LN3@main
$LN2@main:
mov
eax, DWORD PTR _i$[ebp]
add
eax, 1
mov
DWORD PTR _i$[ebp], eax
$LN3@main:
cmp
DWORD PTR _i$[ebp], 30
; 0000001eH
jge
SHORT $LN1@main
mov
ecx, DWORD PTR _i$[ebp]
mov
edx, DWORD PTR _i$[ebp]
; . .
mov
DWORD PTR _a$[ebp+ecx*4], edx ; ECX.
jmp
SHORT $LN2@main
$LN1@main:
xor
eax, eax
mov
esp, ebp
pop
ebp
ret
0
_main
ENDP

, . . ,
.
88

Java, Python,

71

1.14.
1.
, , -, , .
, tracer 6.0.1 , .
, . , :
generic tracer 0.4 (WIN32), http://conus.info/gt
New process: C:\PRJ\...\1.exe, PID=7988
EXCEPTION_ACCESS_VIOLATION: 0x15 (<symbol (0x15) is in unknown module>), ExceptionInformation[0]=8
EAX=0x00000000 EBX=0x7EFDE000 ECX=0x0000001D EDX=0x0000001D
ESI=0x00000000 EDI=0x00000000 EBP=0x00000014 ESP=0x0018FF48
EIP=0x00000015
FLAGS=PF ZF IF RF
PID=7988|Process exit, return code -1073740791

, .
0x15. ,
win32-! - , , . EBP
0x14, ECX EDX 0x1D.
.
main(), EBP. ,
+ i 84 . (20+1)*sizeof(int). ESP
_i PUSH -, -
_i.
main():
ESP
ESP+4
ESP+84
ESP+88

4 i
80 a[20]
EBP

a[19]=_ int ( !)
a[20]=_ _ EBP.
. , 20- 20. , ,
EBP. (20 0x14 ). RET, POP EIP.
RET ( - CRT),
main()), 21 , 0x15 . 0x15, , .
! buffer overflow 89 .
int ( char), ,
, , ,
, . , ,
90 .
GCC 4.4.1. :
main

public main
proc near

a
i

= dword ptr -54h


= dword ptr -4
push
mov
sub
mov
jmp
89
90

ebp
ebp, esp
esp, 60h
[ebp+i], 0
short loc_80483D1

http://en.wikipedia.org/wiki/Stack_buffer_overflow
: [18]

72

1.14.

1.

loc_80483C3:
mov
mov
mov
add

eax, [ebp+i]
edx, [ebp+i]
[ebp+eax*4+a], edx
[ebp+i], 1

cmp
jle
mov
leave
retn
endp

[ebp+i], 1Dh
short loc_80483C3
eax, 0

loc_80483D1:

main

Linux : Segmentation fault.


GDB, :
(gdb) r
Starting program: /home/dennis/RE/1
Program received signal SIGSEGV, Segmentation fault.
0x00000016 in ?? ()
(gdb) info registers
eax
0x0
0
ecx
0xd2f96388
-755407992
edx
0x1d
29
ebx
0x26eff4 2551796
esp
0xbffff4b0
0xbffff4b0
ebp
0x15
0x15
esi
0x0
0
edi
0x0
0
eip
0x16
0x16
eflags
0x10202 [ IF RF ]
cs
0x73
115
ss
0x7b
123
ds
0x7b
123
es
0x7b
123
fs
0x0
0
gs
0x33
51
(gdb)

win32, .

1.14.3

, /++.
MSVC 91 :
/RTCs Stack Frame runtime checking
/GZ Enable stack checks (/RTCs)

, , , . ,
RET ( ). ,
.
92 , 93 ,
, , .
, .
(1.14.1) MSVC94 RTC1
RTCs, @_RTC_CheckStackVars@8,
.
, GCC. alloca() (1.2.1):
#include <malloc.h>
#include <stdio.h>
91

Wikipedia: ,
canary
93
:
94
Microsoft Visual C++
92

73

1.14.

1.

void f()
{
char *buf=(char*)alloca (600);
_snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3);
puts (buf);
};

, , GCC 4.7.3 :
Listing 1.58: GCC 4.7.3
.LC0:
.string "hi! %d, %d, %d\n"
f:
push
mov
push
sub
lea
and
mov
mov
mov
mov
mov
mov
mov
mov
xor
call
mov
call
mov
xor
jne
mov
leave
ret

ebp
ebp, esp
ebx
esp, 676
ebx, [esp+39]
ebx, -16
DWORD PTR [esp+20], 3
DWORD PTR [esp+16], 2
DWORD PTR [esp+12], 1
DWORD PTR [esp+8], OFFSET FLAT:.LC0
DWORD PTR [esp+4], 600
DWORD PTR [esp], ebx
eax, DWORD PTR gs:20
DWORD PTR [ebp-12], eax
eax, eax
_snprintf
DWORD PTR [esp], ebx
puts
eax, DWORD PTR [ebp-12]
eax, DWORD PTR gs:20
.L5
ebx, DWORD PTR [ebp-4]

call

__stack_chk_fail

; "hi! %d, %d, %d\n"

; canary

; canary

.L5:

gs:20. , , ,
gs:20. ,
__stack_chk_fail - (Ubuntu 13.04 x86):
*** buffer overflow detected ***: ./2_1 terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x63)[0xb7699bc3]
/lib/i386-linux-gnu/libc.so.6(+0x10593a)[0xb769893a]
/lib/i386-linux-gnu/libc.so.6(+0x105008)[0xb7698008]
/lib/i386-linux-gnu/libc.so.6(_IO_default_xsputn+0x8c)[0xb7606e5c]
/lib/i386-linux-gnu/libc.so.6(_IO_vfprintf+0x165)[0xb75d7a45]
/lib/i386-linux-gnu/libc.so.6(__vsprintf_chk+0xc9)[0xb76980d9]
/lib/i386-linux-gnu/libc.so.6(__sprintf_chk+0x2f)[0xb7697fef]
./2_1[0x8048404]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb75ac935]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 2097586
/home/dennis/2_1
08049000-0804a000 r--p 00000000 08:01 2097586
/home/dennis/2_1
0804a000-0804b000 rw-p 00001000 08:01 2097586
/home/dennis/2_1
094d1000-094f2000 rw-p 00000000 00:00 0
[heap]
b7560000-b757b000 r-xp 00000000 08:01 1048602
/lib/i386-linux-gnu/libgcc_s.so.1
b757b000-b757c000 r--p 0001a000 08:01 1048602
/lib/i386-linux-gnu/libgcc_s.so.1
b757c000-b757d000 rw-p 0001b000 08:01 1048602
/lib/i386-linux-gnu/libgcc_s.so.1
b7592000-b7593000 rw-p 00000000 00:00 0
b7593000-b7740000 r-xp 00000000 08:01 1050781
/lib/i386-linux-gnu/libc-2.17.so
b7740000-b7742000 r--p 001ad000 08:01 1050781
/lib/i386-linux-gnu/libc-2.17.so
b7742000-b7743000 rw-p 001af000 08:01 1050781
/lib/i386-linux-gnu/libc-2.17.so
b7743000-b7746000 rw-p 00000000 00:00 0
b775a000-b775d000 rw-p 00000000 00:00 0
b775d000-b775e000 r-xp 00000000 00:00 0
[vdso]
b775e000-b777e000 r-xp 00000000 08:01 1050794
/lib/i386-linux-gnu/ld-2.17.so
b777e000-b777f000 r--p 0001f000 08:01 1050794
/lib/i386-linux-gnu/ld-2.17.so
b777f000-b7780000 rw-p 00020000 08:01 1050794
/lib/i386-linux-gnu/ld-2.17.so

74

1.14.

1.

bff35000-bff56000 rw-p 00000000 00:00 0


Aborted (core dumped)

[stack]

gs , MSDOS DOS-. . , Linux gs


TLS (3.6) ,
(, win32 fs, TIB95 96 ).
Linux ( , 3.11):
arch/x86/include/asm/stackprotector.h .
Xcode (LLVM) + thumb-2
(1.14.1), LLVM :
_main
var_64
var_60
var_5C
var_58
var_54
var_50
var_4C
var_48
var_44
var_40
var_3C
var_38
var_34
var_30
var_2C
var_28
var_24
var_20
var_1C
var_18
canary
var_10

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

-0x64
-0x60
-0x5C
-0x58
-0x54
-0x50
-0x4C
-0x48
-0x44
-0x40
-0x3C
-0x38
-0x34
-0x30
-0x2C
-0x28
-0x24
-0x20
-0x1C
-0x18
-0x14
-0x10

PUSH
ADD
STR.W
SUB
MOVW
MOVS
MOVT.W
MOVS
ADD
LDR.W
LDR.W
STR
MOVS
STR
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
95
96

{R4-R7,LR}
R7, SP, #0xC
R8, [SP,#0xC+var_10]!
SP, SP, #0x54
R0, #aObjc_methtype ; "objc_methtype"
R2, #0
R0, #0
R5, #0
R0, PC
R8, [R0]
R0, [R8]
R0, [SP,#0x64+canary]
R0, #2
R2, [SP,#0x64+var_64]
R0, [SP,#0x64+var_60]
R0, #4
R0, [SP,#0x64+var_5C]
R0, #6
R0, [SP,#0x64+var_58]
R0, #8
R0, [SP,#0x64+var_54]
R0, #0xA
R0, [SP,#0x64+var_50]
R0, #0xC
R0, [SP,#0x64+var_4C]
R0, #0xE
R0, [SP,#0x64+var_48]
R0, #0x10
R0, [SP,#0x64+var_44]

Thread Information Block


https://en.wikipedia.org/wiki/Win32_Thread_Information_Block

75

1.14.

1.
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOVS
STR
MOV
MOV
ADDS
ADD
B

R0, #0x12
R0, [SP,#0x64+var_40]
R0, #0x14
R0, [SP,#0x64+var_3C]
R0, #0x16
R0, [SP,#0x64+var_38]
R0, #0x18
R0, [SP,#0x64+var_34]
R0, #0x1A
R0, [SP,#0x64+var_30]
R0, #0x1C
R0, [SP,#0x64+var_2C]
R0, #0x1E
R0, [SP,#0x64+var_28]
R0, #0x20
R0, [SP,#0x64+var_24]
R0, #0x22
R0, [SP,#0x64+var_20]
R0, #0x24
R0, [SP,#0x64+var_1C]
R0, #0x26
R0, [SP,#0x64+var_18]
R4, 0xFDA ; "a[%d]=%d\n"
R0, SP
R6, R0, #4
R4, PC
loc_2F1C

; second loop begin


loc_2F14
ADDS
LDR.W
MOV

R0, R5, #1
R2, [R6,R5,LSL#2]
R5, R0

MOV
MOV
BLX
CMP
BNE
LDR.W
LDR
CMP
ITTTT EQ
MOVEQ
ADDEQ
LDREQ.W
POPEQ
BLX

R0, R4
R1, R5
_printf
R5, #0x13
loc_2F14
R0, [R8]
R1, [SP,#0x64+canary]
R0, R1
; canary still correct?
R0, #0
SP, SP, #0x54
R8, [SP+0x64+var_64],#4
{R4-R7,PC}
___stack_chk_fail

loc_2F1C

-, , LLVM ,
, LLVM . , ARM
.
,
R8. ,
ITTTT EQ, 0 R0, . , ___stack_chk_fail, , ,
.

1.14.4

, /++ - 97 :
void f(int size)
{
int a[size];
...
97

, C99 [12, 6.7.5/2]: GCC


( alloca() (1.2.1))

76

1.14.

1.

};

, (
), , , ,
.
, , , malloc(), , .
C99 [12, 6.7.5/2], alloca() (1.2.1)

1.14.5

, .
, . ,
.
, [3][4] 12- :
0
4
8

1
5
9

2
6
10

3
7
11

, , 4 ( ),
. row-major order,
/++, Python. row-major order - : , . . .
.
column-major order ( ) FORTRAN, MATLAB, R. column-major order - : , . . .
.
.
:
Listing 1.59:
#include <stdio.h>
int a[10][20][30];
void insert(int x, int y, int z, int value)
{
a[x][y][z]=value;
};

x86
(MSVC 2010):
Listing 1.60: MSVC 2010
_DATA
SEGMENT
COMM
_a:DWORD:01770H
_DATA
ENDS
PUBLIC
_insert
_TEXT
SEGMENT
_x$ = 8
;
_y$ = 12
;
_z$ = 16
;
_value$ = 20
;
_insert
PROC
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR
imul
eax, 2400

size
size
size
size

=
=
=
=

4
4
4
4

_x$[ebp]
; eax=600*4*x

77

1.14.
mov
imul
lea
mov
mov
mov
pop
ret
_insert
_TEXT

1.

ecx, DWORD PTR _y$[ebp]


ecx, 120
edx, DWORD PTR _a[eax+ecx]
eax, DWORD PTR _z$[ebp]
ecx, DWORD PTR _value$[ebp]
DWORD PTR [edx+eax*4], ecx
ebp
0
ENDP
ENDS

; ecx=30*4*y
; edx=a + 600*4*x + 30*4*y

; *(edx+z*4)=value

, . insert() ,
= 600 4 + 30 4 + 4,
. int 32- (4 ),
4.
Listing 1.61: GCC 4.4.1
insert

public insert
proc near

x
y
z
value

=
=
=
=

insert

push
mov
push
mov
mov
mov
lea
mov
shl
sub
imul
add
lea
mov
mov
pop
pop
retn
endp

dword
dword
dword
dword

ptr
ptr
ptr
ptr

8
0Ch
10h
14h

ebp
ebp, esp
ebx
ebx, [ebp+x]
eax, [ebp+y]
ecx, [ebp+z]
edx, [eax+eax]
eax, edx
eax, 4
eax, edx
edx, ebx, 600
eax, edx
edx, [eax+ecx]
eax, [ebp+value]
dword ptr ds:a[edx*4], eax
ebx
ebp

;
;
;
;
;
;
;

edx=y*2
eax=y*2
eax=(y*2)<<4 = y*2*16 = y*32
eax=y*32 - y*2=y*30
edx=x*600
eax=eax+edx=y*30 + x*600
edx=y*30 + x*600 + z

; *(a+edx*4)=value

GCC . (30), GCC , . : ( + ) 4 ( + ) = (2) 4 2 =


216 2 = 32 2 = 30. , 30 ,
. .
ARM + Xcode (LLVM) + thumb
Listing 1.62: Xcode (LLVM) + thumb
_insert
value
z
y
x

=
=
=
=

-0x10
-0xC
-8
-4

SUB
MOV
ADD
LDR.W
STR
STR
STR
STR
LDR
LDR

SP,
R9,
R9,
R9,
R0,
R1,
R2,
R3,
R0,
R1,

SP, #0x10 ; allocate place in local stack for 4 int values


0xFC2 ; a
PC
[R9]
[SP,#0x10+x]
[SP,#0x10+y]
[SP,#0x10+z]
[SP,#0x10+value]
[SP,#0x10+value]
[SP,#0x10+z]

78

1.15.

1.

LDR
LDR
MOV
MUL.W
ADD
MOV
MUL.W
ADD
LSLS
ADD
STR
ADD
BX

R2, [SP,#0x10+y]
R3, [SP,#0x10+x]
R12, 2400
R3, R3, R12
R3, R9
R9, 120
R2, R2, R9
R2, R3
R1, R1, #2 ; R1=R1<<2
R1, R2
R0, [R1]
; R1 - address of array element
SP, SP, #0x10 ; deallocate place in local stack for 4 int values
LR

LLVM , .
.
ARM + Xcode (LLVM) + thumb
Listing 1.63: Xcode (LLVM) + thumb
_insert
MOVW
MOV.W
MOVT.W
RSB.W
ADD
LDR.W
MLA.W
ADD.W
STR.W
BX

R9, #0x10FC
R12, #2400
R9, #0
R1, R1, R1,LSL#4
R9, PC
R9, [R9]
R0, R0, R12, R9
R0, R0, R1,LSL#3

; R1 - y. R1=y<<4 - y = y*16 - y = y*15


; R9 = pointer to a array

;
;
;
R3, [R0,R2,LSL#2] ;
;
LR

R0 - x, R12 - 2400, R9 - pointer to a. R0=x*2400 + ptr to a


R0 = R0+R1<<3 = R0+R1*8 = x*2400 + ptr to a + y*15*8 =
ptr to a + y*30*4 + x*600*4
R2 - z, R3 - value. address=R0+z*4 =
ptr to a + y*30*4 + x*600*4 + z*4

, .
RSB (Reverse Subtract). SUB, . ? SUB, RSB, ,
, : (LSL#4).
. , , . ,
, RSB.
LDR.W R9, [R9] LEA (11.5.6) x86, , . , .

1.15

98 . ,
, bool, .

1.15.1

x86
Win32 API:
HANDLE fh;
fh=CreateFile ("file", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
98

bit fields

79

1.15.
(MSVC 2010):

1.

Listing 1.64: MSVC 2010


push
push
push
push
push
push
push
call
mov

0
128
4
0
1
-1073741824
OFFSET $SG78813
DWORD PTR __imp__CreateFileA@28
DWORD PTR _fh$[ebp], eax

; 00000080H

; c0000000H

WinNT.h:
Listing 1.65: WinNT.h
#define
#define
#define
#define

GENERIC_READ
GENERIC_WRITE
GENERIC_EXECUTE
GENERIC_ALL

(0x80000000L)
(0x40000000L)
(0x20000000L)
(0x10000000L)

, GENERIC_READ | GENERIC_WRITE = 0x80000000 | 0x40000000 = 0xC0000000,


CreateFile()99 function.
CreateFile() ?
KERNEL32.DLL Windows XP SP3 x86 CreateFileW()
:
Listing 1.66: KERNEL32.DLL (Windows XP SP3 x86)
.text:7C83D429
.text:7C83D42D
.text:7C83D434
.text:7C83D436

test
mov
jz
jmp

byte ptr [ebp+dwDesiredAccess+3], 40h


[ebp+var_8], 1
short loc_7C83D417
loc_7C810817

TEST, , ,
(ebp+dwDesiredAccess+3) 0x40 (
GENERIC_WRITE).
TEST AND, ( CMP SUB,
(1.4.5)).
:
if ((dwDesiredAccess&0x40000000) == 0) goto loc_7C83D417

AND , ZF JZ
. dwDesiredAccess 0x40000000
AND 0, ZF .
GCC 4.4.1 Linux:
#include <stdio.h>
#include <fcntl.h>
void main()
{
int handle;
handle=open ("file", O_RDWR | O_CREAT);
};

:
Listing 1.67: GCC 4.4.1
main

public main
proc near

var_20
var_1C

= dword ptr -20h


= dword ptr -1Ch

99

MSDN: CreateFile function

80

1.15.

1.

var_4

= dword ptr -4

main

push
mov
and
sub
mov
mov
call
mov
leave
retn
endp

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 20h
[esp+20h+var_1C], 42h
[esp+20h+var_20], offset aFile ; "file"
_open
[esp+20h+var_4], eax

open() libc.so.6, :
Listing 1.68: open() (libc.so.6)
.text:000BE69B
.text:000BE69F
.text:000BE6A3
.text:000BE6A7
.text:000BE6AC

mov
mov
mov
mov
int

edx,
ecx,
ebx,
eax,
80h

[esp+4+mode] ; mode
[esp+4+flags] ; flags
[esp+4+filename] ; filename
5
; LINUX - sys_open

, open() - Linux.
, Linux Linux ,
.
, sys_open, do_sys_open
Linux 2.6. do_filp_open() ( fs/namei.c).
N.B. ,
. fastcall (3.4.3). ,
. GCC
regparm100 , , .
Linux 2.6 -mregparm=3 101 102 .
, EAX, EDX
ECX, . , ,
.
, 2.6.31, Ubuntu: make vmlinux, IDA,
do_filp_open(). ( ):
Listing 1.69: do_filp_open() (linux kernel 2.6.31)
do_filp_open
...

proc near
push
mov
push
push
push
mov
add
sub
mov
test
mov
mov
mov
jnz
mov

ebp
ebp, esp
edi
esi
ebx
ebx, ecx
ebx, 1
esp, 98h
esi, [ebp+arg_4] ; acc_mode ( )
bl, 3
[ebp+var_80], eax ; dfd ( )
[ebp+var_7C], edx ; pathname ( )
[ebp+var_78], ecx ; open_flag ( )
short loc_C01EF684
ebx, ecx
; EBX <- open_flag

GCC . ,
, , (
register allocator), ..
:
100

http://ohse.de/uwe/articles/gcc-attributes.html#func-regparm
http://kernelnewbies.org/Linux_2_6_20#head-042c62f290834eb1fe0a1942bbf5bb9a4accbc8f
102
. arch\x86\include\asm\calling.h
101

81

1.15.
loc_C01EF6B4:
test
jnz
mov
shr
xor
and
test
jz
or

1.
Listing 1.70: do_filp_open() (linux kernel 2.6.31)
; CODE XREF: do_filp_open+4F
bl, 40h
; O_CREAT
loc_C01EF810
edi, ebx
edi, 11h
edi, 1
edi, 1
ebx, 10000h
short loc_C01EF6D3
edi, 2

0x40 O_CREAT. open_flag 0x40


1, JNZ .
ARM
Linux 3.8.0 O_CREAT .
Listing 1.71: linux kernel 3.8.0
struct file *do_filp_open(int dfd, struct filename *pathname,
const struct open_flags *op)
{
...
filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
...
}
static struct file *path_openat(int dfd, struct filename *pathname,
struct nameidata *nd, const struct open_flags *op, int flags)
{
...
error = do_last(nd, &path, file, op, &opened, pathname);
...
}

static int do_last(struct nameidata *nd, struct path *path,


struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
...
if (!(open_flag & O_CREAT)) {
...
error = lookup_fast(nd, path, &inode);
...
} else {
...
error = complete_walk(nd);
}
...
}

IDA, ARM:
Listing 1.72: do_last() (vmlinux)
...
.text:C0169EA8
...
.text:C0169ED4
...
.text:C0169F68
.text:C0169F6C
.text:C0169F70
.text:C0169F74
.text:C0169F78
.text:C0169F7C
.text:C0169F80
.text:C0169F84
.text:C0169F88
.text:C0169F8C
.text:C0169F90

MOV

R9, R3

LDR

R6, [R9] ; R6 - open_flag

TST
BNE
LDR
ADD
LDR
MOV
STR
LDRB
MOV
CMP
ORRNE

R6, #0x40 ; jumptable C0169F00 default case


loc_C016A128
R2, [R4,#0x10]
R12, R4, #8
R3, [R4,#0xC]
R0, R4
R12, [R11,#var_50]
R3, [R2,R3]
R2, R8
R3, #0
R1, R1, #3

82

; R3 - (4th argument) open_flag

1.15.
.text:C0169F94
.text:C0169F98
.text:C0169F9C
.text:C0169FA0
.text:C0169FA4
.text:C0169FA8
.text:C0169FAC
.text:C0169FB0
.text:C0169FB4
...
.text:C016A128 loc_C016A128
.text:C016A128
.text:C016A12C
...

1.
STRNE
ANDS
MOV
LDRNE
ANDNE
EORNE
STR
SUB
BL

R1, [R4,#0x24]
R3, R6, #0x200000
R1, R12
R3, [R4,#0x24]
R3, R3, #1
R3, R3, #1
R3, [R11,#var_54]
R3, R11, #-var_38
lookup_fast

MOV
BL

; CODE XREF: do_last.isra.14+DC


R0, R4
complete_walk

TST TEST x86.



lookup_fast(), complete_walk(). do_last().
O_CREAT 0x40.

1.15.2

:
#define IS_SET(flag, bit)
#define SET_BIT(var, bit)
#define REMOVE_BIT(var, bit)

((flag) & (bit))


((var) |= (bit))
((var) &= ~(bit))

int f(int a)
{
int rt=a;
SET_BIT (rt, 0x4000);
REMOVE_BIT (rt, 0x200);
return rt;
};

x86
(MSVC 2010):
Listing 1.73: MSVC 2010
_rt$ = -4
_a$ = 8
_f PROC
push
mov
push
mov
mov
mov
or
mov
mov
and
mov
mov
mov
pop
ret
_f ENDP

; size = 4
; size = 4
ebp
ebp, esp
ecx
eax, DWORD PTR _a$[ebp]
DWORD PTR _rt$[ebp], eax
ecx, DWORD PTR _rt$[ebp]
ecx, 16384
; 00004000H
DWORD PTR _rt$[ebp], ecx
edx, DWORD PTR _rt$[ebp]
edx, -513
; fffffdffH
DWORD PTR _rt$[ebp], edx
eax, DWORD PTR _rt$[ebp]
esp, ebp
ebp
0

OR , .
AND . , AND , .
, AND , ,
, ( 0 ). .
MSVC (/Ox), :
83

1.15.
_a$ = 8
_f
PROC
mov
and
or
ret
_f
ENDP

1.
Listing 1.74: MSVC
; size = 4

eax, DWORD PTR _a$[esp-4]


eax, -513
; fffffdffH
eax, 16384
; 00004000H
0

GCC 4.4.1 :
Listing 1.75: GCC
f

public f
proc near

var_4
arg_0

= dword ptr -4
= dword ptr 8

push
mov
sub
mov
mov
or
and
mov
leave
retn
endp

ebp
ebp, esp
esp, 10h
eax, [ebp+arg_0]
[ebp+var_4], eax
[ebp+var_4], 4000h
[ebp+var_4], 0FFFFFDFFh
eax, [ebp+var_4]

, MSVC .
GCC -O3:
Listing 1.76: GCC
f

public f
proc near

arg_0

= dword ptr

push
mov
mov
pop
or
and
retn
endp

ebp
ebp, esp
eax, [ebp+arg_0]
ebp
ah, 40h
ah, 0FDh

. AH, EAX,
8- 15- .
7 ( )

5 4 3
RAXx64

EAX
AX
AH AL
N.B. 16- 8086 AX 8-
AL ( ) AH (). 80386 32-,
EAX, ,
AX/AH/AL.
- x86 16- 8086, 16-
32-. , or ah, 40h 3 .
or eax, 04000h, 5 , 6 (
EAX).
-O3,
regparm=3, , :
84

1.15.

1.
Listing 1.77: GCC

public f
proc near
push
ebp
or
ah, 40h
mov
ebp, esp
and
ah, 0FDh
pop
ebp
retn
endp

EAX, .
, (push ebp / mov ebp,esp) (pop ebp)
, GCC
. , ,
inline- (1.22).
ARM + Keil + ARM
Listing 1.78: Keil + ARM
02 0C C0 E3
01 09 80 E3
1E FF 2F E1

BIC
ORR
BX

R0, R0, #0x200


R0, R0, #0x4000
LR

BIC , AND x86. ORR , OR x86.


.
ARM + Keil + thumb
Listing 1.79: Keil + thumb
01
08
49
88
70

21 89 03
43
11
43
47

MOVS
ORRS
ASRS
BICS
BX

R1,
R0,
R1,
R0,
LR

0x4000
R1
R1, #5
R1

; generate 0x200 and place to R1

, Keil thumb, 0x200 0x4000, , 0x200 - .


, ASRS ( ),
0x4000 5.
ARM + Xcode (LLVM) + ARM
Listing 1.80: Xcode (LLVM) + ARM
42 0C C0 E3
01 09 80 E3
1E FF 2F E1

BIC
ORR
BX

R0, R0, #0x4200


R0, R0, #0x4000
LR

, LLVM, , , :
REMOVE_BIT (rt, 0x4200);
SET_BIT (rt, 0x4000);

. 0x4200? ,
LLVM 103 . , , .
, (8.2).
Thumb, Xcode (LLVM) .
103

LLVM build 2410.2.00 Apple Xcode 4.6.3

85

1.15.

1.15.3

1.

/++ .
, -
:
#define IS_SET(flag, bit)

((flag) & (bit))

int f(unsigned int a)


{
int i;
int rt=0;
for (i=0; i<32; i++)
if (IS_SET (a, 1<<i))
rt++;
return rt;
};

, i 0 31, 1 1 0x80000000.
, . .., , 1
32- . ,
. IS_SET a.

CF

IS_SET (AND) 0 ,
, . /++, if() ,
, 123456, .
x86
(MSVC 2010):
Listing 1.81: MSVC 2010
_rt$ = -8
_i$ = -4
_a$ = 8
_f
PROC
push
mov
sub
mov
mov
jmp
$LN3@f:
mov
add
mov
$LN4@f:
cmp
jge
mov
mov
shl
and
je
mov
add
mov
$LN1@f:
jmp

; size = 4
; size = 4
; size = 4
ebp
ebp, esp
esp, 8
DWORD PTR _rt$[ebp], 0
DWORD PTR _i$[ebp], 0
SHORT $LN4@f
eax, DWORD PTR _i$[ebp]
eax, 1
DWORD PTR _i$[ebp], eax

; i

DWORD PTR _i$[ebp], 32


SHORT $LN2@f
edx, 1
ecx, DWORD PTR _i$[ebp]
edx, cl
edx, DWORD PTR _a$[ebp]
SHORT $LN1@f

; 00000020H
; ?

; EDX=EDX<<CL

;
;
eax, DWORD PTR _rt$[ebp] ;
eax, 1
;
DWORD PTR _rt$[ebp], eax

AND 0?

,
rt

SHORT $LN3@f

86

1.15.
$LN2@f:
mov
mov
pop
ret
_f
ENDP

1.

eax, DWORD PTR _rt$[ebp]


esp, ebp
ebp
0

SHL (SHift Left).


GCC 4.4.1:
Listing 1.82: GCC 4.4.1
f

public f
proc near

rt
i
arg_0

= dword ptr -0Ch


= dword ptr -8
= dword ptr 8
push
mov
push
sub
mov
mov
jmp

ebp
ebp, esp
ebx
esp, 10h
[ebp+rt], 0
[ebp+i], 0
short loc_80483EF

mov
mov
mov
mov
shl
mov
and
test
jz
add

eax, [ebp+i]
edx, 1
ebx, edx
ecx, eax
ebx, cl
eax, ebx
eax, [ebp+arg_0]
eax, eax
short loc_80483EB
[ebp+rt], 1

add

[ebp+i], 1

cmp
jle
mov
add
pop
pop
retn
endp

[ebp+i], 1Fh
short loc_80483D0
eax, [ebp+rt]
esp, 10h
ebx
ebp

loc_80483D0:

loc_80483EB:
loc_80483EF:

-
(1, 2, 4, 8, ).
:
unsigned int f(unsigned int a)
{
return a/4;
};

(MSVC 2010):
Listing 1.83: MSVC 2010
_a$ = 8
_f
PROC
mov
shr
ret
_f
ENDP

; size = 4
eax, DWORD PTR _a$[esp-4]
eax, 2
0

SHR (SHift Right) 2 . , (.., ), . 2


. , .
SHR SHL, .
87

1.15.

1.

CF

, , 23. 23
10 (3 ).
2 .
. 4 2 , 2
( ). 3 100 .
ARM + Xcode (LLVM) + ARM
Listing 1.84: Xcode (LLVM) + ARM
MOV
MOV
MOV
MOV

R1,
R0,
R2,
R3,

R0
#0
#1
R0

TST
ADD
ADDNE
CMP
BNE
BX

R1, R2,LSL R3 ; set flags according to R1 & (R2<<R3)


R3, R3, #1
; R3++
R0, R0, #1
; if ZF flag is cleared by TST, R0++
R3, #32
loc_2E54
LR

loc_2E54

TST TEST x86.


(1.12.2), ARM . , LSL (Logical Shift Left), LSR (Logical Shift Right), ASR (Arithmetic Shift Right), ROR (Rotate Right)
RRX (Rotate Right with Extend) , MOV, TST, CMP, ADD, SUB,
RSB104 .
, , .
, TST R1, R2,LSL R3 1 (2 3).
ARM + Xcode (LLVM) + thumb-2
, LSL.W/TST TST,
thumb LSL TST.
MOV
MOVS
MOV.W
MOVS

R1,
R0,
R9,
R3,

R0
#0
#1
#0

LSL.W
TST
ADD.W
IT NE
ADDNE
CMP
BNE
BX

R2, R9, R3
R2, R1
R3, R3, #1

loc_2F7A

1.15.4

R0, #1
R3, #32
loc_2F7A
LR

CRC32

CRC32105 .
104
105

data processing instructions


: http://burtleburtle.net/bob/c/crc.c

88

1.15.

1.

/* By Bob Jenkins, (c) 2006, Public Domain */


#include <stdio.h>
#include <stddef.h>
#include <string.h>
typedef
typedef

unsigned long
unsigned char

ub4;
ub1;

static const ub4 crctab[256] = {


0x00000000, 0x77073096, 0xee0e612c,
0xe963a535, 0x9e6495a3, 0x0edb8832,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0xf3b97148, 0x84be41de, 0x1adad47d,
0x136c9856, 0x646ba8c0, 0xfd62f97a,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x26d930ac, 0x51de003a, 0xc8d75180,
0xcfba9599, 0xb8bda50f, 0x2802b89e,
0x2f6f7c87, 0x58684c11, 0xc1611dab,
0x98d220bc, 0xefd5102a, 0x71b18589,
0x7807c9a2, 0x0f00f934, 0x9609a88e,
0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf,
0x4db26158, 0x3ab551ce, 0xa3bc0074,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x44042d73, 0x33031de5, 0xaa0a4c5f,
0xbe0b1010, 0xc90c2086, 0x5768b525,
0x5edef90e, 0x29d9c998, 0xb0d09822,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320,
0xead54739, 0x9dd277af, 0x04db2615,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b,
0xf00f9344, 0x8708a3d2, 0x1e01f268,
0x196c3671, 0x6e6b06e7, 0xfed41b76,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x316e8eef, 0x4669be79, 0xcb61b38c,
0xcc0c7795, 0xbb0b4703, 0x220216b9,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x72076785, 0x05005713, 0x95bf4a82,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
0x68ddb3f8, 0x1fda836e, 0x81be16cd,
0x88085ae6, 0xff0f6a70, 0x66063bca,
0x616bffd3, 0x166ccf45, 0xa00ae278,
0xa7672661, 0xd06016f7, 0x4969474d,
0x40df0b66, 0x37d83bf0, 0xa9bcae53,
0xbdbdf21c, 0xcabac28a, 0x53b39330,
0x54de5729, 0x23d967bf, 0xb3667a2e,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
};

0x990951ba,
0x79dcb8a4,
0x90bf1d91,
0x6ddde4eb,
0x8a65c9ec,
0x4c69105e,
0xa50ab56b,
0x45df5c75,
0xbfd06116,
0x5f058808,
0xb6662d3d,
0x06b6b51f,
0xe10e9818,
0x1c6c6162,
0xf50fc457,
0x15da2d49,
0xd4bb30e2,
0x346ed9fc,
0xdd0d7cc9,
0x206f85b3,
0xc7d7a8b4,
0x9abfb3b6,
0x73dc1683,
0x9309ff9d,
0x6906c2fe,
0x89d32be0,
0x60b08ed5,
0xa6bc5767,
0x41047a60,
0xbc66831a,
0x5505262f,
0xb5d0cf31,
0x026d930a,
0xe2b87a14,
0x0bdbdf21,
0xf6b9265b,
0x11010b5c,
0xd70dd2ee,
0x3e6e77db,
0xdebb9ec5,
0x24b4a3a6,
0xc4614ab8,
0x2d02ef8d,

0x076dc419,
0xe0d5e91e,
0x1db71064,
0xf4d4b551,
0x14015c4f,
0xd56041e4,
0x35b5a8fa,
0xdcd60dcf,
0x21b4f4b5,
0xc60cd9b2,
0x76dc4190,
0x9fbfe4a5,
0x7f6a0dbb,
0x856530d8,
0x65b0d9c6,
0x8cd37cf3,
0x4adfa541,
0xad678846,
0x5005713c,
0xb966d409,
0x59b33d17,
0x03b6e20c,
0xe3630b12,
0x0a00ae27,
0xf762575d,
0x10da7a5a,
0xd6d6a3e8,
0x3fb506dd,
0xdf60efc3,
0x256fd2a0,
0xc5ba3bbe,
0x2cd99e8b,
0x9c0906a9,
0x7bb12bae,
0x86d3d2d4,
0x6fb077e1,
0x8f659eff,
0x4e048354,
0xaed16a4a,
0x47b2cf7f,
0xbad03605,
0x5d681b02,

0x706af48f,
0x97d2d988,
0x6ab020f2,
0x83d385c7,
0x63066cd9,
0xa2677172,
0x42b2986c,
0xabd13d59,
0x56b3c423,
0xb10be924,
0x01db7106,
0xe8b8d433,
0x086d3d2d,
0xf262004e,
0x12b7e950,
0xfbd44c65,
0x3dd895d7,
0xda60b8d0,
0x270241aa,
0xce61e49f,
0x2eb40d81,
0x74b1d29a,
0x94643b84,
0x7d079eb1,
0x806567cb,
0x67dd4acc,
0xa1d1937e,
0x48b2364b,
0xa867df55,
0x5268e236,
0xb2bd0b28,
0x5bdeae1d,
0xeb0e363f,
0x0cb61b38,
0xf1d4e242,
0x18b74777,
0xf862ae69,
0x3903b3c2,
0xd9d65adc,
0x30b5ffe9,
0xcdd70693,
0x2a6f2b94,

/* how to derive the values in crctab[] from polynomial 0xedb88320 */


void build_table()
{
ub4 i, j;
for (i=0; i<256; ++i) {
j = i;
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
j = (j>>1) ^ ((j&1) ? 0xedb88320 : 0);
printf("0x%.8lx, ", j);
if (i%6 == 5) printf("\n");
}
}

/* the hash function */

89

1.15.

1.

ub4 crc(const void *key, ub4 len, ub4 hash)


{
ub4 i;
const ub1 *k = key;
for (hash=len, i=0; i<len; ++i)
hash = (hash >> 8) ^ crctab[(hash & 0xff) ^ k[i]];
return hash;
}
/* To use, try "gcc -O crc.c -o crc; crc < crc.c" */
int main()
{
char s[1000];
while (gets(s)) printf("%.8lx\n", crc(s, strlen(s), 0));
return 0;
}

crc(). , for():
hash=len, i=0. /++, , . ,
, .
MSVC (/Ox). , crc(), .
_key$ = 8
; size = 4
_len$ = 12
; size = 4
_hash$ = 16
; size = 4
_crc
PROC
mov
edx, DWORD PTR _len$[esp-4]
xor
ecx, ecx ; i ECX
mov
eax, edx
test
edx, edx
jbe
SHORT $LN1@crc
push
ebx
push
esi
mov
esi, DWORD PTR _key$[esp+4] ; ESI = key
push
edi
$LL3@crc:
; 32- . EDI key+i
movzx
mov
and

;
;
;
;

edi, BYTE PTR [ecx+esi]


ebx, eax ; EBX = (hash = len)
ebx, 255 ; EBX = hash & 0xff

XOR EDI, EBX (EDI=EDI^EBX) - 32


(8-31) ,
EDI MOVZX
EBX AND EBX, 255 (255 = 0xff)
xor

edi, ebx

; EAX=EAX>>8; ( 24-31)
shr
eax, 8
; EAX=EAX^crctab[EDI*4] xor
eax, DWORD PTR
inc
ecx
cmp
ecx, edx
jb
SHORT $LL3@crc
pop
edi
pop
esi
pop
ebx
$LN1@crc:
ret
0
_crc
ENDP

crctab[] EDI
_crctab[edi*4]
; i++
; i<len ?
;

GCC 4.4.1 -O3:


crc

public crc
proc near

key
hash

= dword ptr
= dword ptr

8
0Ch

90

1.16.

1.

push
xor
mov
push
mov
push
mov
test
mov
jz
nop
lea

ebp
edx, edx
ebp, esp
esi
esi, [ebp+key]
ebx
ebx, [ebp+hash]
ebx, ebx
eax, ebx
short loc_80484D3
;
esi, [esi+0]
; ; ESI

mov
xor
add
shr
movzx
mov
xor
cmp
ja

ecx, eax
; ECX
al, [esi+edx]
; AL=*(key+i)
edx, 1
; i++
ecx, 8
; ECX=hash>>8
eax, al
; EAX=*(key+i)
eax, dword ptr ds:crctab[eax*4] ; EAX=crctab[EAX]
eax, ecx
; hash=EAX^ECX
ebx, edx
short loc_80484B8

pop
pop
pop
retn
endp

ebx
esi
ebp

loc_80484B8:

loc_80484D3:

crc
\

GCC 8- , NOP lea esi,


[esi+0] ( ). npad (3.2).

1.16

, /++ , , ,
, , 106 .

1.16.1

SYSTEMTIME

, , SYSTEMTIME107 win32 .
:
Listing 1.85: WinBase.h
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;

:
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME t;
GetSystemTime (&t);
106
107

AKA
MSDN: SYSTEMTIME structure

91

1.16.

1.

printf ("%04d-%02d-%02d %02d:%02d:%02d\n",


t.wYear, t.wMonth, t.wDay,
t.wHour, t.wMinute, t.wSecond);
return;
};

(MSVC 2010):
Listing 1.86: MSVC 2010
_t$ = -16
_main
push
mov
sub
lea
push
call
movzx
push
movzx
push
movzx
push
movzx
push
movzx
push
movzx
push
push
call
add
xor
mov
pop
ret
_main

; size = 16
PROC
ebp
ebp, esp
esp, 16
; 00000010H
eax, DWORD PTR _t$[ebp]
eax
DWORD PTR __imp__GetSystemTime@4
ecx, WORD PTR _t$[ebp+12] ; wSecond
ecx
edx, WORD PTR _t$[ebp+10] ; wMinute
edx
eax, WORD PTR _t$[ebp+8] ; wHour
eax
ecx, WORD PTR _t$[ebp+6] ; wDay
ecx
edx, WORD PTR _t$[ebp+2] ; wMonth
edx
eax, WORD PTR _t$[ebp] ; wYear
eax
OFFSET $SG78811 ; %04d-%02d-%02d %02d:%02d:%02d, 0aH, 00H
_printf
esp, 28
; 0000001cH
eax, eax
esp, ebp
ebp
0
ENDP

16 sizeof(WORD)*8 ( 8
WORD).
wYear.
GetSystemTime()108 SYSTEMTIME, , wYear, ! GetSystemTime()
WORD , 2 ,
, , .
,
. SYSTEMTIME,
:
#include <windows.h>
#include <stdio.h>
void main()
{
WORD array[8];
GetSystemTime (array);
printf ("%04d-%02d-%02d %02d:%02d:%02d\n",
array[0] /* wYear */, array[1] /* wMonth */, array[3] /* wDay */,
array[4] /* wHour */, array[5] /* wMinute */, array[6] /* wSecond */);
return;
};

:
systemtime2.c(7) : warning C4133: function : incompatible types - from WORD [8] to LPSYSTEMTIME
108

MSDN: GetSystemTime function

92

1.16.
, :

1.

Listing 1.87: MSVC 2010


$SG78573 DB
_array$ = -16
_main
PROC
push
mov
sub
lea
push
call
movzx
push
movzx
push
movzx
push
movzx
push
movzx
push
movzx
push
push
call
add
xor
mov
pop
ret
_main
ENDP

%04d-%02d-%02d %02d:%02d:%02d, 0aH, 00H


; size = 16
ebp
ebp, esp
esp, 16
; 00000010H
eax, DWORD PTR _array$[ebp]
eax
DWORD PTR __imp__GetSystemTime@4
ecx, WORD PTR _array$[ebp+12] ; wSecond
ecx
edx, WORD PTR _array$[ebp+10] ; wMinute
edx
eax, WORD PTR _array$[ebp+8] ; wHoure
eax
ecx, WORD PTR _array$[ebp+6] ; wDay
ecx
edx, WORD PTR _array$[ebp+2] ; wMonth
edx
eax, WORD PTR _array$[ebp] ; wYear
eax
OFFSET $SG78573
_printf
esp, 28
; 0000001cH
eax, eax
esp, ebp
ebp
0

!
. , ,
, , .
, . . , ,
, , .

1.16.2

malloc()

, , :
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME *t;
t=(SYSTEMTIME *)malloc (sizeof (SYSTEMTIME));
GetSystemTime (t);
printf ("%04d-%02d-%02d %02d:%02d:%02d\n",
t->wYear, t->wMonth, t->wDay,
t->wHour, t->wMinute, t->wSecond);
free (t);
return;
};

(/Ox) , .
Listing 1.88: MSVC
_main
push
push
call

PROC
esi
16
_malloc

; 00000010H

93

1.16.
add
mov
push
call
movzx
movzx
movzx
push
movzx
push
movzx
push
movzx
push
push
push
push
call
push
call
add
xor
pop
ret
_main

1.

esp, 4
esi, eax
esi
DWORD PTR __imp__GetSystemTime@4
eax, WORD PTR [esi+12] ; wSecond
ecx, WORD PTR [esi+10] ; wMinute
edx, WORD PTR [esi+8] ; wHour
eax
eax, WORD PTR [esi+6] ; wDay
ecx
ecx, WORD PTR [esi+2] ; wMonth
edx
edx, WORD PTR [esi] ; wYear
eax
ecx
edx
OFFSET $SG78833
_printf
esi
_free
esp, 32
; 00000020H
eax, eax
esi
0
ENDP

, sizeof(SYSTEMTIME) = 16, malloc().


EAX, ESI. Win32
GetSystemTime() ESI,
GetSystemTime().
MOVZX (Move with Zero eXtent). MOVSX (1.11.1),
0. printf() 32- int,
WORD 16- . WORD int,
16 31, , .
WORD-:
#include <windows.h>
#include <stdio.h>
void main()
{
WORD *t;
t=(WORD *)malloc (16);
GetSystemTime (t);
printf ("%04d-%02d-%02d %02d:%02d:%02d\n",
t[0] /* wYear */, t[1] /* wMonth */, t[3] /* wDay */,
t[4] /* wHour */, t[5] /* wMinute */, t[6] /* wSecond */);
free (t);
return;
};

:
Listing 1.89: MSVC
$SG78594 DB
_main

PROC
push
push
call
add
mov
push
call
movzx
movzx
movzx

%04d-%02d-%02d %02d:%02d:%02d, 0aH, 00H

esi
16
_malloc
esp, 4
esi, eax
esi
DWORD PTR
eax, WORD
ecx, WORD
edx, WORD

; 00000010H

__imp__GetSystemTime@4
PTR [esi+12]
PTR [esi+10]
PTR [esi+8]

94

1.16.

_main

push
movzx
push
movzx
push
movzx
push
push
push
push
call
push
call
add
xor
pop
ret
ENDP

1.

eax
eax, WORD PTR [esi+6]
ecx
ecx, WORD PTR [esi+2]
edx
edx, WORD PTR [esi]
eax
ecx
edx
OFFSET $SG78594
_printf
esi
_free
esp, 32
eax, eax
esi
0

; 00000020H

, . ,
.

1.16.3

struct tm

Linux
, , tm time.h:
#include <stdio.h>
#include <time.h>
void main()
{
struct tm t;
time_t unix_time;
unix_time=time(NULL);
localtime_r (&unix_time, &t);
printf
printf
printf
printf
printf
printf

("Year: %d\n", t.tm_year+1900);


("Month: %d\n", t.tm_mon);
("Day: %d\n", t.tm_mday);
("Hour: %d\n", t.tm_hour);
("Minutes: %d\n", t.tm_min);
("Seconds: %d\n", t.tm_sec);

};

GCC 4.4.1:
Listing 1.90: GCC 4.4.1
main

proc near
push
ebp
mov
ebp, esp
and
esp, 0FFFFFFF0h
sub
esp, 40h
mov
dword ptr [esp], 0 ; time()
call
time
mov
[esp+3Ch], eax
lea
eax, [esp+3Ch] ; time()
lea
edx, [esp+10h] ; ESP+10h struct tm
mov
[esp+4], edx
;
mov
[esp], eax
; time()
call
localtime_r
mov
eax, [esp+24h] ; tm_year
lea
edx, [eax+76Ch] ; edx=eax+1900
mov
eax, offset format ; "Year: %d\n"
mov
[esp+4], edx
mov
[esp], eax
call
printf
mov
edx, [esp+20h]
; tm_mon
mov
eax, offset aMonthD ; "Month: %d\n"
mov
[esp+4], edx

95

1.16.

main

mov
call
mov
mov
mov
mov
call
mov
mov
mov
mov
call
mov
mov
mov
mov
call
mov
mov
mov
mov
call
leave
retn
endp

1.
[esp], eax
printf
edx, [esp+1Ch]
; tm_mday
eax, offset aDayD ; "Day: %d\n"
[esp+4], edx
[esp], eax
printf
edx, [esp+18h]
; tm_hour
eax, offset aHourD ; "Hour: %d\n"
[esp+4], edx
[esp], eax
printf
edx, [esp+14h]
; tm_min
eax, offset aMinutesD ; "Minutes: %d\n"
[esp+4], edx
[esp], eax
printf
edx, [esp+10h]
eax, offset aSecondsD ; "Seconds: %d\n"
[esp+4], edx
; tm_sec
[esp], eax
printf

, - , IDA .
:-) .
lea edx, [eax+76Ch] 0x76C EAX,
. . LEA (11.5.6).
,
, time.h:
Listing 1.91: time.h
struct tm
{
int
tm_sec;
int
tm_min;
int
tm_hour;
int
tm_mday;
int
tm_mon;
int
tm_year;
int
tm_wday;
int
tm_yday;
int
tm_isdst;
};
#include <stdio.h>
#include <time.h>
void main()
{
int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday, tm_yday, tm_isdst;
time_t unix_time;
unix_time=time(NULL);
localtime_r (&unix_time, &tm_sec);
printf
printf
printf
printf
printf
printf

("Year: %d\n", tm_year+1900);


("Month: %d\n", tm_mon);
("Day: %d\n", tm_mday);
("Hour: %d\n", tm_hour);
("Minutes: %d\n", tm_min);
("Seconds: %d\n", tm_sec);

};

N.B. localtime_r tm_sec, .., .


, :
Listing 1.92: GCC 4.7.3
96

1.16.

1.

GCC_tm2.c: In function main:


GCC_tm2.c:11:5: warning: passing argument 2 of localtime_r from incompatible pointer type [enabled by
default]
In file included from GCC_tm2.c:2:0:
/usr/include/time.h:59:12: note: expected struct tm * but argument is of type int *

, :
Listing 1.93: GCC 4.7.3
main

proc near

var_30
var_2C
unix_time
tm_sec
tm_min
tm_hour
tm_mday
tm_mon
tm_year

=
=
=
=
=
=
=
=
=

main

push
mov
and
sub
call
mov
call
mov
lea
mov
lea
mov
call
mov
add
mov
mov
call
mov
mov
mov
call
mov
mov
mov
call
mov
mov
mov
call
mov
mov
mov
call
mov
mov
mov
call
leave
retn
endp

dword
dword
dword
dword
dword
dword
dword
dword
dword

ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr

-30h
-2Ch
-1Ch
-18h
-14h
-10h
-0Ch
-8
-4

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 30h
__main
[esp+30h+var_30], 0 ; arg 0
time
[esp+30h+unix_time], eax
eax, [esp+30h+tm_sec]
[esp+30h+var_2C], eax
eax, [esp+30h+unix_time]
[esp+30h+var_30], eax
localtime_r
eax, [esp+30h+tm_year]
eax, 1900
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aYearD ; "Year: %d\n"
printf
eax, [esp+30h+tm_mon]
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aMonthD ; "Month: %d\n"
printf
eax, [esp+30h+tm_mday]
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aDayD ; "Day: %d\n"
printf
eax, [esp+30h+tm_hour]
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aHourD ; "Hour: %d\n"
printf
eax, [esp+30h+tm_min]
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aMinutesD ; "Minutes: %d\n"
printf
eax, [esp+30h+tm_sec]
[esp+30h+var_2C], eax
[esp+30h+var_30], offset aSecondsD ; "Seconds: %d\n"
printf

, ,
.
. , . ,
, . ,
.
, - , tm_year, tm_mon,
tm_mday, tm_hour, tm_min, tm_sec, . , localtime_r().

97

1.16.
1.
, int,
SYSTEMTIME 16- WORD, , ,
32- ( GetSystemTime()
). : .
, , .
, . , , , , .
, -, ( 1972) [22].
ARM + Keil + thumb
:
Listing 1.94: Keil + thumb
var_38
var_34
var_30
var_2C
var_28
var_24
timer

=
=
=
=
=
=
=

-0x38
-0x34
-0x30
-0x2C
-0x28
-0x24
-0xC

PUSH
MOVS
SUB
BL
STR
MOV
ADD
BL
LDR
LDR
ADDS
ADR
BL
LDR
ADR
BL
LDR
ADR
BL
LDR
ADR
BL
LDR
ADR
BL
LDR
ADR
BL
ADD
POP

{LR}
R0, #0
; timer
SP, SP, #0x34
time
R0, [SP,#0x38+timer]
R1, SP
; tp
R0, SP, #0x38+timer ; timer
localtime_r
R1, =0x76C
R0, [SP,#0x38+var_24]
R1, R0, R1
R0, aYearD
; "Year: %d\n"
__2printf
R1, [SP,#0x38+var_28]
R0, aMonthD
; "Month: %d\n"
__2printf
R1, [SP,#0x38+var_2C]
R0, aDayD
; "Day: %d\n"
__2printf
R1, [SP,#0x38+var_30]
R0, aHourD
; "Hour: %d\n"
__2printf
R1, [SP,#0x38+var_34]
R0, aMinutesD
; "Minutes: %d\n"
__2printf
R1, [SP,#0x38+var_38]
R0, aSecondsD
; "Seconds: %d\n"
__2printf
SP, SP, #0x34
{PC}

ARM + Xcode (LLVM) + thumb-2

IDA tm ( IDA , localtime_r(


.
Listing 1.95: Xcode (LLVM) + thumb-2
var_38
var_34

= -0x38
= -0x34
PUSH
MOV
SUB
MOVS
BLX

{R7,LR}
R7, SP
SP, SP, #0x30
R0, #0 ; time_t *
_time

98

1.16.
ADD
STR
MOV
BLX
LDR
MOV
ADD
ADDW
BLX
LDR
MOV
ADD
BLX
LDR
MOV
ADD
BLX
LDR
MOV
ADD
BLX
LDR
MOV
ADD
BLX
LDR
MOV
ADD
BLX
ADD
POP

1.
R1, SP, #0x38+var_34 ; struct tm *
R0, [SP,#0x38+var_38]
R0, SP ; time_t *
_localtime_r
R1, [SP,#0x38+var_34.tm_year]
R0, 0xF44 ; "Year: %d\n"
R0, PC ; char *
R1, R1, #0x76C
_printf
R1, [SP,#0x38+var_34.tm_mon]
R0, 0xF3A ; "Month: %d\n"
R0, PC ; char *
_printf
R1, [SP,#0x38+var_34.tm_mday]
R0, 0xF35 ; "Day: %d\n"
R0, PC ; char *
_printf
R1, [SP,#0x38+var_34.tm_hour]
R0, 0xF2E ; "Hour: %d\n"
R0, PC ; char *
_printf
R1, [SP,#0x38+var_34.tm_min]
R0, 0xF28 ; "Minutes: %d\n"
R0, PC ; char *
_printf
R1, [SP,#0x38+var_34]
R0, 0xF25 ; "Seconds: %d\n"
R0, PC ; char *
_printf
SP, SP, #0x30
{R7,PC}

...
00000000
00000000
00000004
00000008
0000000C
00000010
00000014
00000018
0000001C
00000020
00000024
00000028
0000002C

tm
tm_sec
tm_min
tm_hour
tm_mday
tm_mon
tm_year
tm_wday
tm_yday
tm_isdst
tm_gmtoff
tm_zone
tm

struc ; (sizeof=0x2C, standard type)


DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
DCD ?
; offset
ends

1.16.4

, 109 .
:
#include <stdio.h>
struct s
{
char a;
int b;
char c;
int d;
};
void f(struct s s)
{
printf ("a=%d; b=%d; c=%d; d=%d\n", s.a, s.b, s.c, s.d);
};

, char ( ) int ( 4 ).
109

.: Wikipedia:

99

1.16.
x86

1.

:
_s$ = 8
; size = 16
?f@@YAXUs@@@Z PROC
; f
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR _s$[ebp+12]
push
eax
movsx ecx, BYTE PTR _s$[ebp+8]
push
ecx
mov
edx, DWORD PTR _s$[ebp+4]
push
edx
movsx eax, BYTE PTR _s$[ebp]
push
eax
push
OFFSET $SG3842
call
_printf
add
esp, 20
; 00000014H
pop
ebp
ret
0
?f@@YAXUs@@@Z ENDP
; f
_TEXT
ENDS

4- .
char 4 int. ?
.
.
(/Zp1) (/Zp[n] pack structs on n-byte boundary).
Listing 1.96: MSVC /Zp1
_TEXT
SEGMENT
_s$ = 8
; size = 10
?f@@YAXUs@@@Z PROC
; f
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR _s$[ebp+6]
push
eax
movsx ecx, BYTE PTR _s$[ebp+5]
push
ecx
mov
edx, DWORD PTR _s$[ebp+1]
push
edx
movsx eax, BYTE PTR _s$[ebp]
push
eax
push
OFFSET $SG3842
call
_printf
add
esp, 20
; 00000014H
pop
ebp
ret
0
?f@@YAXUs@@@Z ENDP
; f

10 char . ? . .
, ,
.
MSVC /Zp, , , #pragma pack, . MSVC110
GCC111 .
SYSTEMTIME, 16- .
?
WinNT.h :
Listing 1.97: WinNT.h
#include "pshpack1.h"
110
111

MSDN: Working with Packing Structures


Structure-Packing Pragmas

100

1.16.
:

1.

Listing 1.98: WinNT.h


#include "pshpack4.h"

// 4 byte packing is the default

PshPack1.h :
Listing 1.99: PshPack1.h
#if ! (defined(lint) || defined(RC_INVOKED))
#if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
#pragma warning(disable:4103)
#if !(defined( MIDL_PASS )) || defined( __midl )
#pragma pack(push,1)
#else
#pragma pack(1)
#endif
#else
#pragma pack(1)
#endif
#endif /* ! (defined(lint) || defined(RC_INVOKED)) */

, , #pragma pack .
ARM + Keil + thumb
Listing 1.100: Keil + thumb
.text:0000003E
.text:0000003E 05 B0
.text:00000040 00 BD

exit

.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000280
.text:00000282
.text:00000284
.text:00000286
.text:00000288
.text:0000028A
.text:0000028C
.text:0000028E
.text:00000290
.text:00000292
.text:00000296

f
var_18
a
b
c
d
0F
81
04
02
00
68
03
01
59
05
D2

B5
B0
98
9A
90
46
7B
79
A0
F0 AD FF
E6

; CODE XREF: f+16


ADD
POP

=
=
=
=
=

SP, SP, #0x14


{PC}

-0x18
-0x14
-0x10
-0xC
-8

PUSH
SUB
LDR
LDR
STR
MOV
LDRB
LDRB
ADR
BL
B

{R0-R3,LR}
SP, SP, #4
R0, [SP,#16]
R2, [SP,#8]
R0, [SP]
R0, SP
R3, [R0,#12]
R1, [R0,#4]
R0, aADBDCDDD
__2printf
exit

; d
; b

; c
; a
; "a=%d; b=%d; c=%d; d=%d\n"

, , , ARM
4 , R0-R3.
LDRB 32- .
MOVSX (1.11.1) x86. .
, , !
, , , , ,
(, 5 (5 * 4 = 014)). ,
( ). , , ,
. Keil , , - . 4
, 2.
ARM + Xcode (LLVM) + thumb-2

101

1.16.
var_C

1.
Listing 1.101: Xcode (LLVM) + thumb-2

= -0xC
PUSH
MOV
SUB
MOV
MOV
MOVW
SXTB
MOVT.W
STR
ADD
SXTB
MOV
BLX
ADD
POP

{R7,LR}
R7, SP
SP, SP, #4
R9, R1 ; b
R1, R0 ; a
R0, #0xF10 ; "a=%d; b=%d; c=%d; d=%d\n"
R1, R1 ; prepare a
R0, #0
R3, [SP,#0xC+var_C] ; place d to stack for printf()
R0, PC ; format-string
R3, R2 ; prepare c
R2, R9 ; b
_printf
SP, SP, #4
{R7,PC}

SXTB (Signed Extend Byte) MOVSX (1.11.1) x86, ,


. .

1.16.5

, , ?
#include <stdio.h>
struct inner_struct
{
int a;
int b;
};
struct outer_struct
{
char a;
int b;
struct inner_struct c;
char d;
int e;
};
void f(struct outer_struct s)
{
printf ("a=%d; b=%d; c.a=%d; c.b=%d; d=%d; e=%d\n",
s.a, s.b, s.c.a, s.c.b, s.d, s.e);
};

. . . , inner_struct a,b d,e outer_struct.


(MSVC 2010):
Listing 1.102: MSVC 2010
_s$ = 8
_f
PROC
push
mov
mov
push
movsx
push
mov
push
mov
push
mov
push
movsx
push
push
call
add

; size = 24
ebp
ebp, esp
eax, DWORD PTR _s$[ebp+20] ; e
eax
ecx, BYTE PTR _s$[ebp+16] ; d
ecx
edx, DWORD PTR _s$[ebp+12] ; c.b
edx
eax, DWORD PTR _s$[ebp+8] ; c.a
eax
ecx, DWORD PTR _s$[ebp+4] ; b
ecx
edx, BYTE PTR _s$[ebp] ;a
edx
OFFSET $SG2466
_printf
esp, 28
; 0000001cH

102

1.16.
_f

1.

pop
ebp
ret
0
ENDP

, , , - ! , , ,
, .
, struct inner_struct c; struct inner_struct *c;
( ), .

1.16.6

CPUID
/++ , .
. , bool . ,
, .
CPUID112 . ,
.
EAX 1, CPUID EAX :
3:0
7:4
11:8
13:12
19:16
27:20

Stepping
Model
Family
Processor Type
Extended Model
Extended Family

MSVC 2010 CPUID, GCC 4.4.1 . GCC ,


113 .
#include <stdio.h>
#ifdef __GNUC__
static inline void cpuid(int code, int *a, int *b, int *c, int *d) {
asm volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code));
}
#endif
#ifdef _MSC_VER
#include <intrin.h>
#endif
struct CPUID_1_EAX
{
unsigned int stepping:4;
unsigned int model:4;
unsigned int family_id:4;
unsigned int processor_type:2;
unsigned int reserved1:2;
unsigned int extended_model_id:4;
unsigned int extended_family_id:8;
unsigned int reserved2:4;
};
int main()
{
struct CPUID_1_EAX *tmp;
int b[4];
#ifdef _MSC_VER
__cpuid(b,1);
112
113

http://en.wikipedia.org/wiki/CPUID
GCC

103

1.16.

1.

#endif
#ifdef __GNUC__
cpuid (1, &b[0], &b[1], &b[2], &b[3]);
#endif
tmp=(struct CPUID_1_EAX *)&b[0];
printf
printf
printf
printf
printf
printf

("stepping=%d\n", tmp->stepping);
("model=%d\n", tmp->model);
("family_id=%d\n", tmp->family_id);
("processor_type=%d\n", tmp->processor_type);
("extended_model_id=%d\n", tmp->extended_model_id);
("extended_family_id=%d\n", tmp->extended_family_id);

return 0;
};

CPUID EAX/EBX/ECX/EDX, b[]. ,


CPUID_1_EAX, EAX b[].
, 32- int .
.
MSVC 2008 /Ox:
Listing 1.103: MSVC 2008
_b$ = -16
_main
PROC
sub
esp, 16
push
ebx

; size = 16
; 00000010H

xor
mov
cpuid
push
lea
mov
mov
mov
mov

ecx, ecx
eax, 1

mov
mov
and
push
push
call

esi, DWORD PTR _b$[esp+24]


eax, esi
eax, 15
; 0000000fH
eax
OFFSET $SG15435 ; stepping=%d, 0aH, 00H
_printf

mov
shr
and
push
push
call

ecx, esi
ecx, 4
ecx, 15
; 0000000fH
ecx
OFFSET $SG15436 ; model=%d, 0aH, 00H
_printf

mov
shr
and
push
push
call

edx, esi
edx, 8
edx, 15
; 0000000fH
edx
OFFSET $SG15437 ; family_id=%d, 0aH, 00H
_printf

mov
shr
and
push
push
call

eax, esi
eax, 12
; 0000000cH
eax, 3
eax
OFFSET $SG15438 ; processor_type=%d, 0aH, 00H
_printf

mov
shr
and
push
push
call

ecx, esi
ecx, 16
; 00000010H
ecx, 15
; 0000000fH
ecx
OFFSET $SG15439 ; extended_model_id=%d, 0aH, 00H
_printf

esi
esi, DWORD PTR _b$[esp+24]
DWORD PTR [esi], eax
DWORD PTR [esi+4], ebx
DWORD PTR [esi+8], ecx
DWORD PTR [esi+12], edx

104

1.16.

1.

shr
and
push
push
call
add
pop

esi, 20
; 00000014H
esi, 255
; 000000ffH
esi
OFFSET $SG15440 ; extended_family_id=%d, 0aH, 00H
_printf
esp, 48
; 00000030H
esi

xor
pop

eax, eax
ebx

add
ret
_main

esp, 16
0
ENDP

; 00000010H

SHR EAX , , ,
.
AND , , ,
EAX, .
GCC 4.4.1 -O3.
Listing 1.104: GCC 4.4.1
main
push
mov
and
push
mov
push
mov
sub
cpuid
mov
and
mov
mov
mov
call
mov
shr
and
mov
mov
mov
call
mov
shr
and
mov
mov
mov
call
mov
shr
and
mov
mov
mov
call
mov
shr
shr
and
and
mov
mov
mov
call
mov
mov
mov
call
add

proc near
ebp
ebp,
esp,
esi
esi,
ebx
eax,
esp,

; DATA XREF: _start+17

esp
0FFFFFFF0h
1
esi
18h

esi, eax
eax, 0Fh
[esp+8], eax
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
eax, esi
eax, 4
eax, 0Fh
[esp+8], eax
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
eax, esi
eax, 8
eax, 0Fh
[esp+8], eax
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
eax, esi
eax, 0Ch
eax, 3
[esp+8], eax
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
eax, esi
eax, 10h
esi, 14h
eax, 0Fh
esi, 0FFh
[esp+8], eax
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
[esp+8], esi
dword ptr [esp+4],
dword ptr [esp], 1
___printf_chk
esp, 18h

offset aSteppingD ; "stepping=%d\n"

offset aModelD ; "model=%d\n"

offset aFamily_idD ; "family_id=%d\n"

offset aProcessor_type ; "processor_type=%d\n"

offset aExtended_model ; "extended_model_id=%d\n"

offset unk_80486D0

105

1.16.
xor
pop
pop
mov
pop
retn
main

1.

eax, eax
ebx
esi
esp, ebp
ebp
endp

, . , GCC -
extended_model_id extended_family_id ,
printf().
float
FPU (1.13), float double , . , ? float.

. 1.1: float114
#include
#include
#include
#include

<stdio.h>
<assert.h>
<stdlib.h>
<memory.h>

struct float_as_struct
{
unsigned int fraction : 23; // fractional part
unsigned int exponent : 8; // exponent + 0x3FF
unsigned int sign : 1;
// sign bit
};
float f(float _in)
{
float f=_in;
struct float_as_struct t;
assert (sizeof (struct float_as_struct) == sizeof (float));
memcpy (&t, &f, sizeof (float));
t.sign=1; // set negative sign
t.exponent=t.exponent+2; // multiple d by 2^n (n here is 2)
memcpy (&f, &t, sizeof (float));
return f;
};
int main()
{
printf ("%f\n", f(1.234));
};

float_as_struct float, 4
32 .
, , 22 , 4.
MSVC 2008 :
Listing 1.105: MSVC 2008
114

wikipedia

106

1.16.
_t$ = -8
_f$ = -4
__in$ = 8
?f@@YAMM@Z
push
mov
sub

1.

;
;
;
;

PROC
ebp
ebp, esp
esp, 8

size = 4
size = 4
size = 4
f

fld
fstp

DWORD PTR __in$[ebp]


DWORD PTR _f$[ebp]

push
lea
push
lea
push
call
add

4
eax, DWORD PTR _f$[ebp]
eax
ecx, DWORD PTR _t$[ebp]
ecx
_memcpy
esp, 12
; 0000000cH

mov
or
mov

edx, DWORD PTR _t$[ebp]


edx, -2147483648 ; 80000000H -
DWORD PTR _t$[ebp], edx

mov
shr
and
add
and
shl
mov
and

eax,
eax,
eax,
eax,
eax,
eax,
ecx,
ecx,

DWORD PTR _t$[ebp]


23
; 00000017H -
255
; 000000ffH -
2
;
255
; 000000ffH
23
; 00000017H - 30:23
DWORD PTR _t$[ebp]
-2139095041 ; 807fffffH -

;
or
ecx, eax
mov
DWORD PTR _t$[ebp], ecx
push
lea
push
lea
push
call
add

4
edx, DWORD PTR _t$[ebp]
edx
eax, DWORD PTR _f$[ebp]
eax
_memcpy
esp, 12
; 0000000cH

fld

DWORD PTR _f$[ebp]

mov
pop
ret
?f@@YAMM@Z

esp, ebp
ebp
0
ENDP

; f

. /Ox memcpy(), f. .
GCC 4.4.1 -O3?
Listing 1.106: GCC 4.4.1
; f(float)
public _Z1ff
_Z1ff proc near
var_4 = dword ptr -4
arg_0 = dword ptr 8
push
mov
sub
mov
or
mov
and
shr
add
movzx
shl
or

ebp
ebp,
esp,
eax,
eax,
edx,
eax,
edx,
edx,
edx,
edx,
eax,

esp
4
[ebp+arg_0]
80000000h ;
eax
807FFFFFh ;
23
;
2
;
dl
;
23
;
edx
;

-
eax

2
7:0 EAX 0

107

1.17. (UNION)
mov
fld
leave
retn
_Z1ff endp

main

main

1.

[ebp+var_4], eax
[ebp+var_4]

public main
proc near
push
ebp
mov
ebp, esp
and
esp, 0FFFFFFF0h
sub
esp, 10h
fld
ds:dword_8048614 ; -4.936
fstp
qword ptr [esp+8]
mov
dword ptr [esp+4], offset asc_8048610 ; "%f\n"
mov
dword ptr [esp], 1
call
___printf_chk
xor
eax, eax
leave
retn
endp

, f() . , , ,
, GCC f(1.234)
printf()!

1.17

(union)

1.17.1

0 1,
115 Mersenne twister 32- DWORD,
float RAND_MAX (0xffffffff )
0 1.
, . ,
? (1.12)
: , .
, !
( ),
01111111 . , 0 ( ), .
1 2, .
116 ,
32- . UNIX.
, float union /++ -. , union float uint32_t. , .
#include <stdio.h>
#include <stdint.h>
#include <time.h>
union uint32_t_float
{
uint32_t i;
float f;
};
// from the Numerical Recipes book
const uint32_t RNG_a=1664525;
const uint32_t RNG_c=1013904223;

115
116


: http://xor0110.wordpress.com/2010/09/24/how-to-generate-floating-point-random-numbers-e

108

1.17. (UNION)

1.

int main()
{
uint32_t_float tmp;
uint32_t RNG_state=time(NULL); // initial seed
for (int i=0; i<100; i++)
{
RNG_state=RNG_state*RNG_a+RNG_c;
tmp.i=RNG_state & 0x007fffff | 0x3F800000;
float x=tmp.f-1;
printf ("%f\n", x);
};
return 0;
};

Listing 1.107: MSVC 2010 (/Ox)


$SG4232

DB

%f, 0aH, 00H

__real@3ff0000000000000 DQ 03ff0000000000000r
tv140 = -4
_tmp$ = -4
_main
PROC
push
ebp
mov
ebp, esp
and
esp, -64
sub
esp, 56
push
esi
push
edi
push
0
call
__time64
add
esp, 4
mov
esi, eax
mov
edi, 100
$LN3@main:

; 1

; size = 4
; size = 4

; ffffffc0H
; 00000038H

; 00000064H

; , 32-
imul
add
mov

esi, 1664525
esi, 1013904223
eax, esi

; 0019660dH
; 3c6ef35fH

;
and

eax, 8388607

; 007fffffH

; 1
or

eax, 1065353216

; 3f800000H

; int
mov
sub

DWORD PTR _tmp$[esp+64], eax


esp, 8

; float
fld

DWORD PTR _tmp$[esp+72]

;
fsub
fstp
fld
fstp
push
call
add
dec
jne
pop
xor
pop
mov

QWORD PTR __real@3ff0000000000000


DWORD PTR tv140[esp+72]
DWORD PTR tv140[esp+72]
QWORD PTR [esp]
OFFSET $SG4232
_printf
esp, 12
; 0000000cH
edi
SHORT $LN3@main
edi
eax, eax
esi
esp, ebp

109

1.18.
pop
ret
_main
_TEXT
END

1.

ebp
0
ENDP
ENDS

GCC .

1.18

, , , .
.. callback- 117 .
:
qsort()118 , atexit()119 ;
*NIX 120 ;
: CreateThread() (win32), pthread_create() (POSIX);
win32, EnumChildWindows()121 .
, qsort() .
, ,
qsort() .
:
int (*compare)(const void *, const void *)

, :
/* ex3 Sorting ints with qsort */
#include <stdio.h>
#include <stdlib.h>
int comp(const void * _a, const void * _b)
{
const int *a=(const int *)_a;
const int *b=(const int *)_b;
if (*a==*b)
return 0;
else
if (*a < *b)
return -1;
else
return 1;
}
int main(int argc, char* argv[])
{
int numbers[10]={1892,45,200,-98,4087,5,-12345,1087,88,-100000};
int i;
/* Sort the array */
qsort(numbers,10,sizeof(int),comp) ;
for (i=0;i<9;i++)
printf("Number = %d\n",numbers[ i ]) ;
return 0;
}
117

http://en.wikipedia.org/wiki/Callback_(computer_science)
http://en.wikipedia.org/wiki/Qsort_(C_standard_library)
119
http://www.opengroup.org/onlinepubs/009695399/functions/atexit.html
120
http://en.wikipedia.org/wiki/Signal.h
121
http://msdn.microsoft.com/en-us/library/ms633494(VS.85).aspx
118

110

1.18.
1.
MSVC 2010 ( ) /Ox:
Listing 1.108: MSVC 2010
__a$ = 8
__b$ = 12
_comp
mov
mov
mov
mov
cmp
jne
xor
ret
$LN4@comp:
xor
cmp
setge
lea
ret
_comp

; size = 4
; size = 4
PROC
eax, DWORD PTR __a$[esp-4]
ecx, DWORD PTR __b$[esp-4]
eax, DWORD PTR [eax]
ecx, DWORD PTR [ecx]
eax, ecx
SHORT $LN4@comp
eax, eax
0
edx, edx
eax, ecx
dl
eax, DWORD PTR [edx+edx-1]
0
ENDP

...
_numbers$ = -44
; size = 40
_i$ = -4
; size = 4
_argc$ = 8
; size = 4
_argv$ = 12
; size = 4
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 44
mov
DWORD PTR _numbers$[ebp], 1892
mov
DWORD PTR _numbers$[ebp+4], 45
mov
DWORD PTR _numbers$[ebp+8], 200
mov
DWORD PTR _numbers$[ebp+12], -98
mov
DWORD PTR _numbers$[ebp+16], 4087
mov
DWORD PTR _numbers$[ebp+20], 5
mov
DWORD PTR _numbers$[ebp+24], -12345
mov
DWORD PTR _numbers$[ebp+28], 1087
mov
DWORD PTR _numbers$[ebp+32], 88
mov
DWORD PTR _numbers$[ebp+36], -100000
push
OFFSET _comp
push
4
push
10
lea
eax, DWORD PTR _numbers$[ebp]
push
eax
call
_qsort
add
esp, 16

;
;
;
;
;
;

0000002cH
00000764H
0000002dH
000000c8H
ffffff9eH
00000ff7H

;
;
;
;

ffffcfc7H
0000043fH
00000058H
fffe7960H

; 0000000aH

; 00000010H

...

. , qsort()
_comp, comp().
qsort() ?
MSVCR80.DLL ( DLL MSVC ):
Listing 1.109: MSVCR80.DLL
.text:7816CBF0
const void
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0
.text:7816CBF0

; void __cdecl qsort(void *, unsigned int, unsigned int, int (__cdecl *)(const void *,
*))
public _qsort
_qsort
proc near
lo
hi
var_FC
stkptr
lostk
histk
base
num
width
comp

=
=
=
=
=
=
=
=
=
=

dword
dword
dword
dword
dword
dword
dword
dword
dword
dword

ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr

-104h
-100h
-0FCh
-0F8h
-0F4h
-7Ch
4
8
0Ch
10h

111

1.18.
.text:7816CBF0
.text:7816CBF0

1.

sub

esp, 100h

shr
imul
add
mov
push
push
call
add
test
jle

; CODE XREF: _qsort+B1


eax, 1
eax, ebp
eax, ebx
edi, eax
edi
ebx
[esp+118h+comp]
esp, 8
eax, eax
short loc_7816CD04

....
.text:7816CCE0 loc_7816CCE0:
.text:7816CCE0
.text:7816CCE2
.text:7816CCE5
.text:7816CCE7
.text:7816CCE9
.text:7816CCEA
.text:7816CCEB
.text:7816CCF2
.text:7816CCF5
.text:7816CCF7

comp .
comp. comp(). ,
.
. -, qsort()
, qsort(), ,
, , .
-, callback- , , ,

.

1.18.1

GCC

:
Listing 1.110: GCC
lea
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
call

eax, [esp+40h+var_28]
[esp+40h+var_40], eax
[esp+40h+var_28], 764h
[esp+40h+var_24], 2Dh
[esp+40h+var_20], 0C8h
[esp+40h+var_1C], 0FFFFFF9Eh
[esp+40h+var_18], 0FF7h
[esp+40h+var_14], 5
[esp+40h+var_10], 0FFFFCFC7h
[esp+40h+var_C], 43Fh
[esp+40h+var_8], 58h
[esp+40h+var_4], 0FFFE7960h
[esp+40h+var_34], offset comp
[esp+40h+var_38], 4
[esp+40h+var_3C], 0Ah
_qsort

comp():
comp

public comp
proc near

arg_0
arg_4

= dword ptr
= dword ptr

8
0Ch

push
mov
mov
mov
mov
xor
cmp
jnz
pop
retn

ebp
ebp, esp
eax, [ebp+arg_4]
ecx, [ebp+arg_0]
edx, [eax]
eax, eax
[ecx], edx
short loc_8048458
ebp

setnl

al

loc_8048458:

112

1.19. SIMD

1.
movzx
lea
pop
retn
endp

comp

eax, al
eax, [eax+eax-1]
ebp

qsort() libc.so.6, qsort_r().


, , quicksort(),
:
Listing 1.111: ( libc.so.6, glibc 2.10.1)
.text:0002DDF6
.text:0002DDF9
.text:0002DDFD
.text:0002DE00
.text:0002DE04
...

1.19

mov
mov
mov
mov
call

edx, [ebp+arg_10]
[esp+4], esi
[esp], edi
[esp+8], edx
[ebp+arg_C]

SIMD

SIMD : Single Instruction, Multiple Data.


, .
FPU, x86.
SIMD x86 MMX. 8 64- MM0-MM7.
MMX- 2 32- , 4 16- 8 . ,
MMX-, 8 8- .
, , . , , ,
, . ,
-- , MMX
.
MMX , FPU-. FPU MMX . Intel
,
,
FPU . , MMX + +
MMX = .
SSE 128 , FPU.
AVX 256 .
.
, (memcpy), (memcmp), .
: DES, 64- , 56- , 64- . DES
, , , , .
bitslice DES122 . , x86
unsigned int 32 ,
32- -, 64+56 unsigned int.
/ Oracle RDBMS ( DES),
bitslice DES SSE2 AVX 128
256 -:
http://conus.info/utils/ops_SIMD/
122

http://www.darkside.com.au/bitslice/

113

1.19. SIMD

1.19.1

1.

123 , , ,
. , -
. .
.
:
Cray Y-MP 1988, - Cray Y-MP EL 124 .
:
for (i = 0; i < 1024; i++)
{
C[i] = A[i]*B[i];
}

A B, C.
32- int,
4 128- XMM-, B XMM- PMULLD ( DWORD ) PMULHW (
DWORD ), 4 64-
.
, 1024/4 1024, 4 , , ,
.
,
Intel C++125 .
:
int f (int sz, int *ar1, int *ar2, int *ar3)
{
for (int i=0; i<sz; i++)
ar3[i]=ar1[i]+ar2[i];
return 0;
};

Intel C++
Intel C++ 11.1.051 win32:
icl intel.cpp /QaxSSE2 /Faintel.asm /Ox
( IDA):
; int __cdecl f(int, int *, int *, int *)
public ?f@@YAHHPAH00@Z
?f@@YAHHPAH00@Z proc near
var_10
sz
ar1
ar2
ar3

=
=
=
=
=

dword
dword
dword
dword
dword

push
push
push
push
mov
test
jle
mov

ptr -10h
ptr 4
ptr 8
ptr 0Ch
ptr 10h
edi
esi
ebx
esi
edx, [esp+10h+sz]
edx, edx
loc_15B
eax, [esp+10h+ar3]

123

Wikipedia: vectorization
. : http://www.cray-cyber.org
125
Intel C++ : Excerpt: Effective Automatic Vectorization
124

114

1.19. SIMD

1.
cmp
jle
cmp
jbe
mov
sub
lea
neg
cmp
jbe

edx, 6
loc_143
eax, [esp+10h+ar2]
short loc_36
esi, [esp+10h+ar2]
esi, eax
ecx, ds:0[edx*4]
esi
ecx, esi
short loc_55

cmp
jnb
mov
sub
lea
cmp
jb

; CODE XREF: f(int,int *,int *,int *)+21


eax, [esp+10h+ar2]
loc_143
esi, [esp+10h+ar2]
esi, eax
ecx, ds:0[edx*4]
esi, ecx
loc_143

cmp
jbe
mov
sub
neg
cmp
jbe

; CODE XREF: f(int,int *,int *,int *)+34


eax, [esp+10h+ar1]
short loc_67
esi, [esp+10h+ar1]
esi, eax
esi
ecx, esi
short loc_7F

cmp
jnb
mov
sub
cmp
jb

; CODE XREF: f(int,int *,int *,int *)+59


eax, [esp+10h+ar1]
loc_143
esi, [esp+10h+ar1]
esi, eax
esi, ecx
loc_143

mov
and
jz
test
jnz
neg
add
shr

edi, eax
edi, 0Fh
short loc_9A
edi, 3
loc_162
edi
edi, 10h
edi, 2

lea
cmp
jl
mov
sub
and
neg
add
test
jbe
mov
mov
mov
xor

; CODE XREF: f(int,int *,int *,int *)+84


ecx, [edi+4]
edx, ecx
loc_162
ecx, edx
ecx, edi
ecx, 3
ecx
ecx, edx
edi, edi
short loc_D6
ebx, [esp+10h+ar2]
[esp+10h+var_10], ecx
ecx, [esp+10h+ar1]
esi, esi

mov
add
mov
inc
cmp
jb
mov
mov

; CODE XREF: f(int,int *,int *,int *)+CD


edx, [ecx+esi*4]
edx, [ebx+esi*4]
[eax+esi*4], edx
esi
esi, edi
short loc_C1
ecx, [esp+10h+var_10]
edx, [esp+10h+sz]

mov
lea

; CODE XREF: f(int,int *,int *,int *)+B2


esi, [esp+10h+ar2]
esi, [esi+edi*4] ; is ar2+i*4 16-byte aligned?

loc_36:

loc_55:

loc_67:

loc_7F:

loc_9A:

loc_C1:

loc_D6:

;
;
;
;

CODE XREF: f(int,int *,int *,int *)+65


edi = ar1
is ar1 16-byte aligned?
yes

115

1.19. SIMD

1.
test
jz
mov
mov

esi, 0Fh
short loc_109
; yes!
ebx, [esp+10h+ar1]
esi, [esp+10h+ar2]

loc_ED:

; CODE XREF: f(int,int *,int *,int *)+105


movdqu xmm1, xmmword ptr [ebx+edi*4]
movdqu xmm0, xmmword ptr [esi+edi*4] ; ar2+i*4 is not 16-byte aligned, so load it to xmm0
paddd
xmm1, xmm0
movdqa xmmword ptr [eax+edi*4], xmm1
add
edi, 4
cmp
edi, ecx
jb
short loc_ED
jmp
short loc_127
; --------------------------------------------------------------------------loc_109:
mov
mov

; CODE XREF: f(int,int *,int *,int *)+E3


ebx, [esp+10h+ar1]
esi, [esp+10h+ar2]

movdqu
paddd
movdqa
add
cmp
jb

; CODE XREF: f(int,int *,int *,int *)+125


xmm0, xmmword ptr [ebx+edi*4]
xmm0, xmmword ptr [esi+edi*4]
xmmword ptr [eax+edi*4], xmm0
edi, 4
edi, ecx
short loc_111

loc_111:

loc_127:

; CODE XREF: f(int,int *,int *,int *)+107


; f(int,int *,int *,int *)+164
cmp
jnb
mov
mov

ecx, edx
short loc_15B
esi, [esp+10h+ar1]
edi, [esp+10h+ar2]

loc_133:

; CODE XREF: f(int,int *,int *,int *)+13F


mov
ebx, [esi+ecx*4]
add
ebx, [edi+ecx*4]
mov
[eax+ecx*4], ebx
inc
ecx
cmp
ecx, edx
jb
short loc_133
jmp
short loc_15B
; --------------------------------------------------------------------------loc_143:
mov
mov
xor

; CODE XREF: f(int,int *,int *,int *)+17


; f(int,int *,int *,int *)+3A ...
esi, [esp+10h+ar1]
edi, [esp+10h+ar2]
ecx, ecx

mov
add
mov
inc
cmp
jb

; CODE XREF: f(int,int *,int *,int *)+159


ebx, [esi+ecx*4]
ebx, [edi+ecx*4]
[eax+ecx*4], ebx
ecx
ecx, edx
short loc_14D

loc_14D:

loc_15B:

; CODE XREF: f(int,int *,int *,int *)+A


; f(int,int *,int *,int *)+129 ...

xor
eax, eax
pop
ecx
pop
ebx
pop
esi
pop
edi
retn
; --------------------------------------------------------------------------loc_162:
xor
jmp
?f@@YAHHPAH00@Z endp

; CODE XREF: f(int,int *,int *,int *)+8C


; f(int,int *,int *,int *)+9F
ecx, ecx
short loc_127

SSE2 :
116

1.19. SIMD
1.
MOVDQU (Move Unaligned Double Quadword) 16 XMM-.
PADDD (Add Packed Integers) 4 32-
. , , , 32 .
PADDD , 16- .
, 126 .
MOVDQA (Move Aligned Double Quadword) MOVDQU,
16- . , . MOVDQA
MOVDQU, .
, SSE2- 4
int ar3 16- .
, ar2 16- , :
movdqu
paddd
movdqa

xmm0, xmmword ptr [ebx+edi*4] ; ar1+i*4


xmm0, xmmword ptr [esi+edi*4] ; ar2+i*4
xmmword ptr [eax+edi*4], xmm0 ; ar3+i*4

, ar2 XMM0 MOVDQU, , :


movdqu
movdqu
paddd
movdqa

xmm1, xmmword ptr [ebx+edi*4] ; ar1+i*4


xmm0, xmmword ptr [esi+edi*4] ; ar2+i*4 is not 16-byte aligned, so load it to xmm0
xmm1, xmm0
xmmword ptr [eax+edi*4], xmm1 ; ar3+i*4

, ,
SSE2.
GCC
GCC - 127 , -O3
SSE2: -msse2.
(GCC 4.4.1):
; f(int, int *, int *, int *)
public _Z1fiPiS_S_
_Z1fiPiS_S_
proc near
var_18
var_14
var_10
arg_0
arg_4
arg_8
arg_C

=
=
=
=
=
=
=

dword
dword
dword
dword
dword
dword
dword

push
mov
push
push
push
sub
mov
mov
mov
mov
test
jle
cmp
lea
ja

126
127

ptr -18h
ptr -14h
ptr -10h
ptr 8
ptr 0Ch
ptr 10h
ptr 14h
ebp
ebp, esp
edi
esi
ebx
esp, 0Ch
ecx, [ebp+arg_0]
esi, [ebp+arg_4]
edi, [ebp+arg_8]
ebx, [ebp+arg_C]
ecx, ecx
short loc_80484D8
ecx, 6
eax, [ebx+10h]
short loc_80484E8

. : Wikipedia:
GCC: http://gcc.gnu.org/projects/tree-ssa/vectorization.html

117

1.19. SIMD

1.

loc_80484C1:

; CODE XREF: f(int,int *,int *,int *)+4B


; f(int,int *,int *,int *)+61 ...
xor
nop
lea

loc_80484C8:
mov
add
mov
add
cmp
jnz

eax, eax
esi, [esi+0]
; CODE XREF: f(int,int *,int *,int *)+36
edx, [edi+eax*4]
edx, [esi+eax*4]
[ebx+eax*4], edx
eax, 1
eax, ecx
short loc_80484C8

loc_80484D8:

; CODE XREF: f(int,int *,int *,int *)+17


; f(int,int *,int *,int *)+A5

add
esp, 0Ch
xor
eax, eax
pop
ebx
pop
esi
pop
edi
pop
ebp
retn
; --------------------------------------------------------------------------align 8
loc_80484E8:
test
jnz
lea
cmp
jbe

; CODE XREF: f(int,int *,int *,int *)+1F


bl, 0Fh
short loc_80484C1
edx, [esi+10h]
ebx, edx
loc_8048578

lea
cmp
ja
cmp
jbe

; CODE XREF: f(int,int *,int *,int *)+E0


edx, [edi+10h]
ebx, edx
short loc_8048503
edi, eax
short loc_80484C1

loc_80484F8:

loc_8048503:
mov
shr
mov
shl
test
mov
jz
mov
mov
xor
xor
nop
loc_8048520:

; CODE XREF: f(int,int *,int *,int *)+5D


eax, ecx
eax, 2
[ebp+var_14], eax
eax, 2
eax, eax
[ebp+var_10], eax
short loc_8048547
[ebp+var_18], ecx
ecx, [ebp+var_14]
eax, eax
edx, edx

movdqu
movdqu
add
paddd
movdqa
add
cmp
jb
mov
mov
cmp
jz

; CODE XREF: f(int,int *,int *,int *)+9B


xmm1, xmmword ptr [edi+eax]
xmm0, xmmword ptr [esi+eax]
edx, 1
xmm0, xmm1
xmmword ptr [ebx+eax], xmm0
eax, 10h
edx, ecx
short loc_8048520
ecx, [ebp+var_18]
eax, [ebp+var_10]
ecx, eax
short loc_80484D8

lea
add
add
add
lea

edx,
esi,
edi,
ebx,
esi,

loc_8048547:

loc_8048558:

; CODE XREF: f(int,int *,int *,int *)+73


ds:0[eax*4]
edx
edx
edx
[esi+0]
; CODE XREF: f(int,int *,int *,int *)+CC

118

1.19. SIMD

1.

mov
edx, [edi]
add
eax, 1
add
edi, 4
add
edx, [esi]
add
esi, 4
mov
[ebx], edx
add
ebx, 4
cmp
ecx, eax
jg
short loc_8048558
add
esp, 0Ch
xor
eax, eax
pop
ebx
pop
esi
pop
edi
pop
ebp
retn
; --------------------------------------------------------------------------loc_8048578:

_Z1fiPiS_S_

; CODE XREF: f(int,int *,int *,int *)+52


cmp
jnb
jmp
endp

eax, esi
loc_80484C1
loc_80484F8

, Intel C++.

1.19.2

strlen() SIMD

, , SIMD- /++ 128 . MSVC, intrin.h.


strlen()129 SIMD-,
2-2.5 . XMM- 16
.
size_t strlen_sse2(const char *str)
{
register size_t len = 0;
const char *s=str;
bool str_is_aligned=(((unsigned int)str)&0xFFFFFFF0) == (unsigned int)str;
if (str_is_aligned==false)
return strlen (str);
__m128i xmm0 = _mm_setzero_si128();
__m128i xmm1;
int mask = 0;
for (;;)
{
xmm1 = _mm_load_si128((__m128i *)s);
xmm1 = _mm_cmpeq_epi8(xmm1, xmm0);
if ((mask = _mm_movemask_epi8(xmm1)) != 0)
{
unsigned long pos;
_BitScanForward(&pos, mask);
len += (size_t)pos;
break;
}
s += sizeof(__m128i);
len += sizeof(__m128i);
};
return len;
}

( ).
MSVC 2010 /Ox:
128
129

MSDN: MMX, SSE, and SSE2 Intrinsics


strlen()

119

1.19. SIMD

1.

_pos$75552 = -4
; size = 4
_str$ = 8
; size = 4
?strlen_sse2@@YAIPBD@Z PROC ; strlen_sse2
push
ebp
mov
ebp, esp
and
esp, -16
; fffffff0H
mov
eax, DWORD PTR _str$[ebp]
sub
esp, 12
; 0000000cH
push
esi
mov
esi, eax
and
esi, -16
; fffffff0H
xor
edx, edx
mov
ecx, eax
cmp
esi, eax
je
SHORT $LN4@strlen_sse
lea
edx, DWORD PTR [eax+1]
npad
3
$LL11@strlen_sse:
mov
cl, BYTE PTR [eax]
inc
eax
test
cl, cl
jne
SHORT $LL11@strlen_sse
sub
eax, edx
pop
esi
mov
esp, ebp
pop
ebp
ret
0
$LN4@strlen_sse:
movdqa
xmm1, XMMWORD PTR [eax]
pxor
xmm0, xmm0
pcmpeqb xmm1, xmm0
pmovmskb eax, xmm1
test
eax, eax
jne
SHORT $LN9@strlen_sse
$LL3@strlen_sse:
movdqa
xmm1, XMMWORD PTR [ecx+16]
add
ecx, 16
; 00000010H
pcmpeqb xmm1, xmm0
add
edx, 16
; 00000010H
pmovmskb eax, xmm1
test
eax, eax
je
SHORT $LL3@strlen_sse
$LN9@strlen_sse:
bsf
eax, eax
mov
ecx, eax
mov
DWORD PTR _pos$75552[esp+16], eax
lea
eax, DWORD PTR [ecx+edx]
pop
esi
mov
esp, ebp
pop
ebp
ret
0
?strlen_sse2@@YAIPBD@Z ENDP
; strlen_sse2

, , str, 16- . ,
strlen().
16 XMM1 MOVDQA.
, MOVDQU,
, ?
, : , MOVDQA,
MOVDQU.
, :
Windows NT, , 4 KiB (4096 ).
win32- 4 GiB, , . ,
, . 130 .
, , 16 , . , 8192 (0x2000) 0x008c0000.
130

http://en.wikipedia.org/wiki/Page_(computer_memory)

120

1.19. SIMD
1.
, 0x008c0000 0x008c1fff .
, 0x008c2000 , ..,
. .
, , ,
, :
0x008c1ff8
0x008c1ff9
0x008c1ffa
0x008c1ffb
0x008c1ffc
0x008c1ffd
0x008c1ffe
0x008c1fff

h
e
l
l
o
\x00

, strlen() hello 0x008c1ff8. strlen() 0x008c1ffd, ,


.
, strlen() 16 , , 16- , MOVDQU 16
0x008c1ff8 0x008c2008, . , , .
16 , 16 ,
.
.
_mm_setzero_si128() , pxor xmm0, xmm0 XMM0.
_mm_load_si128() MOVDQA, 16
XMM1.
_mm_cmpeq_epi8() PCMPEQB, XMM .
- ,
0xff, 0, .
.
XMM1: 11223344556677880000000000000000
XMM0: 11ab3444007877881111111111111111
pcmpeqb xmm1, xmm0, XMM1 :
XMM1: ff0000ff0000ffff0000000000000000
, 16- 16- , XMM0 pxor xmm0, xmm0.
_mm_movemask_epi8() PMOVMSKB.
PCMPEQB.
pmovmskb eax, xmm1
EAX ,
XMM1 . , XMM1 0xff,
EAX , .
XMM1 0xff, EAX .
, , XMM1 0xff?
16 EAX. EAX .
, :
16 hello\x00garbage\x00ab
121

1.20. 64
1.
hello, , .
16 XMM1 XMM0, (
MSB131 LSB132 ):
XMM1: 0000ff00000000000000ff0000000000
, .
PMOVMSKB EAX ( ): 0010000000100000b.
.
BSF (Bit Scan Forward).
.
EAX=0010000000100000b
bsf eax, eax, EAX 5, ,
( ).
, MSVC _BitScanForward.
. ,
.
.
, , MSVC , .
, SSE 4.2 ( Intel Core i7)
: http://www.strchr.com/strcmp_and_strlen_using_sse_4.2

1.20

64

1.20.1

x86-64

x86- 64 .
reverse engineer-, 32- x86 :
( FPU SIMD) 64- r-. 8 . : rax, rbx, rcx, rdx, rbp, rsp,
rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15.
. , 32
RAX EAX.
r8-r15 : r8d-r15d ( 32- ),
r8w-r15w ( 16- ), r8b-r15b ( 8- ).
SIMD-: 8 16: XMM0-XMM15.
win64 , fastcall (3.4.3). 4
RCX, RDX, R8, R9, .
32 4
.

,
.
. (3.4).
int 32- .
131
132

most significant bit


least significant bit

122

1.20. 64
64-.

1.

: 2
, .. -, x64- 48
RAM133 .
- ,
register allocation. ,
.
, S- DES,
32/64/128/256 , DES_type (uint32, uint64, SSE2 AVX),
bitslice DES ( (1.19)):
/*
* Generated S-box files.
*
* This software may be modified, redistributed, and used for any purpose,
* so long as its origin is acknowledged.
*
* Produced by Matthew Kwan - March 1998
*/
#ifdef _WIN64
#define DES_type unsigned __int64
#else
#define DES_type unsigned int
#endif
void
s1 (
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
) {
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type
DES_type

a1,
a2,
a3,
a4,
a5,
a6,
*out1,
*out2,
*out3,
*out4
x1, x2, x3, x4, x5, x6, x7, x8;
x9, x10, x11, x12, x13, x14, x15, x16;
x17, x18, x19, x20, x21, x22, x23, x24;
x25, x26, x27, x28, x29, x30, x31, x32;
x33, x34, x35, x36, x37, x38, x39, x40;
x41, x42, x43, x44, x45, x46, x47, x48;
x49, x50, x51, x52, x53, x54, x55, x56;

x1 = a3 & ~a5;
x2 = x1 ^ a4;
x3 = a3 & ~a4;
x4 = x3 | a5;
x5 = a6 & x4;
x6 = x2 ^ x5;
x7 = a4 & ~a5;
x8 = a3 ^ a4;
x9 = a6 & ~x8;
x10 = x7 ^ x9;
x11 = a2 | x10;
x12 = x6 ^ x11;
x13 = a5 ^ x5;
x14 = x13 & x8;
x15 = a5 & ~a4;
x16 = x3 ^ x14;
x17 = a6 | x16;
x18 = x15 ^ x17;
x19 = a2 | x18;
x20 = x14 ^ x19;
x21 = a1 & x20;
x22 = x12 ^ ~x21;
133

Random-access memory

123

1.20. 64
*out2
x23 =
x24 =
x25 =
x26 =
x27 =
x28 =
x29 =
x30 =
x31 =
x32 =
x33 =
x34 =
x35 =
*out4
x36 =
x37 =
x38 =
x39 =
x40 =
x41 =
x42 =
x43 =
x44 =
x45 =
x46 =
*out1
x47 =
x48 =
x49 =
x50 =
x51 =
x52 =
x53 =
x54 =
x55 =
x56 =
*out3

1.

^= x22;
x1 | x5;
x23 ^ x8;
x18 & ~x2;
a2 & ~x25;
x24 ^ x26;
x6 | x7;
x28 ^ x25;
x9 ^ x24;
x18 & ~x30;
a2 & x31;
x29 ^ x32;
a1 & x33;
x27 ^ x34;
^= x35;
a3 & x28;
x18 & ~x36;
a2 | x3;
x37 ^ x38;
a3 | x31;
x24 & ~x37;
x41 | x3;
x42 & ~a2;
x40 ^ x43;
a1 & ~x44;
x39 ^ ~x45;
^= x46;
x33 & ~x9;
x47 ^ x39;
x4 ^ x36;
x49 & ~x5;
x42 | x18;
x51 ^ a5;
a2 & ~x52;
x50 ^ x53;
a1 | x54;
x48 ^ ~x55;
^= x56;

. , .
MSVC 2008 /Ox:
Listing 1.112: MSVC 2008
PUBLIC
_s1
; Function compile flags: /Ogtpy
_TEXT
SEGMENT
_x6$ = -20
; size = 4
_x3$ = -16
; size = 4
_x1$ = -12
; size = 4
_x8$ = -8
; size = 4
_x4$ = -4
; size = 4
_a1$ = 8
; size = 4
_a2$ = 12
; size = 4
_a3$ = 16
; size = 4
_x33$ = 20
; size = 4
_x7$ = 20
; size = 4
_a4$ = 20
; size = 4
_a5$ = 24
; size = 4
tv326 = 28
; size = 4
_x36$ = 28
; size = 4
_x28$ = 28
; size = 4
_a6$ = 28
; size = 4
_out1$ = 32
; size = 4
_x24$ = 36
; size = 4
_out2$ = 36
; size = 4
_out3$ = 40
; size = 4
_out4$ = 44
; size = 4
_s1
PROC
sub
esp, 20
; 00000014H
mov
edx, DWORD PTR _a5$[esp+16]
push
ebx
mov
ebx, DWORD PTR _a4$[esp+20]
push
ebp
push
esi

124

1.20. 64
mov
push
mov
not
mov
and
mov
not
and
mov
and
and
mov
xor
mov
or
mov
and
mov
mov
xor
mov
mov
xor
mov
xor
mov
and
mov
mov
xor
or
not
and
xor
mov
or
mov
mov
xor
and
mov
xor
not
or
xor
mov
mov
xor
not
xor
and
mov
mov
or
mov
or
mov
xor
mov
xor
not
and
mov
and
xor
xor
not
mov
and
and
xor
mov
xor
xor
mov

1.

esi, DWORD PTR _a3$[esp+28]


edi
edi, ebx
edi
ebp, edi
edi, DWORD PTR _a5$[esp+32]
ecx, edx
ecx
ebp, esi
eax, ecx
eax, esi
ecx, ebx
DWORD PTR _x1$[esp+36], eax
eax, ebx
esi, ebp
esi, edx
DWORD PTR _x4$[esp+36], esi
esi, DWORD PTR _a6$[esp+32]
DWORD PTR _x7$[esp+32], ecx
edx, esi
edx, eax
DWORD PTR _x6$[esp+36], edx
edx, DWORD PTR _a3$[esp+32]
edx, ebx
ebx, esi
ebx, DWORD PTR _a5$[esp+32]
DWORD PTR _x8$[esp+36], edx
ebx, edx
ecx, edx
edx, ebx
edx, ebp
edx, DWORD PTR _a6$[esp+32]
ecx
ecx, DWORD PTR _a6$[esp+32]
edx, edi
edi, edx
edi, DWORD PTR _a2$[esp+32]
DWORD PTR _x3$[esp+36], ebp
ebp, DWORD PTR _a2$[esp+32]
edi, ebx
edi, DWORD PTR _a1$[esp+32]
ebx, ecx
ebx, DWORD PTR _x7$[esp+32]
edi
ebx, ebp
edi, ebx
ebx, edi
edi, DWORD PTR _out2$[esp+32]
ebx, DWORD PTR [edi]
eax
ebx, DWORD PTR _x6$[esp+36]
eax, edx
DWORD PTR [edi], ebx
ebx, DWORD PTR _x7$[esp+32]
ebx, DWORD PTR _x6$[esp+36]
edi, esi
edi, DWORD PTR _x1$[esp+36]
DWORD PTR _x28$[esp+32], ebx
edi, DWORD PTR _x8$[esp+36]
DWORD PTR _x24$[esp+32], edi
edi, ecx
edi
edi, edx
ebx, edi
ebx, ebp
ebx, DWORD PTR _x28$[esp+32]
ebx, eax
eax
DWORD PTR _x33$[esp+32], ebx
ebx, DWORD PTR _a1$[esp+32]
eax, ebp
eax, ebx
ebx, DWORD PTR _out4$[esp+32]
eax, DWORD PTR [ebx]
eax, DWORD PTR _x24$[esp+32]
DWORD PTR [ebx], eax

125

1.20. 64
mov
and
mov
or
mov
not
and
or
xor
not
and
not
or
not
and
or
xor
mov
xor
xor
mov
not
and
not
and
and
xor
or
not
xor
not
and
xor
not
mov
xor
mov
xor
pop
pop
xor
pop
mov
pop
add
ret
_s1

1.

eax, DWORD PTR _x28$[esp+32]


eax, DWORD PTR _a3$[esp+32]
ebx, DWORD PTR _x3$[esp+36]
edi, DWORD PTR _a3$[esp+32]
DWORD PTR _x36$[esp+32], eax
eax
eax, edx
ebx, ebp
ebx, eax
eax
eax, DWORD PTR _x24$[esp+32]
ebp
eax, DWORD PTR _x3$[esp+36]
esi
ebp, eax
eax, edx
eax, DWORD PTR _a5$[esp+32]
edx, DWORD PTR _x36$[esp+32]
edx, DWORD PTR _x4$[esp+36]
ebp, edi
edi, DWORD PTR _out1$[esp+32]
eax
eax, DWORD PTR _a2$[esp+32]
ebp
ebp, DWORD PTR _a1$[esp+32]
edx, esi
eax, edx
eax, DWORD PTR _a1$[esp+32]
ebp
ebp, DWORD PTR [edi]
ecx
ecx, DWORD PTR _x33$[esp+32]
ebp, ebx
eax
DWORD PTR [edi], ebp
eax, ecx
ecx, DWORD PTR _out3$[esp+32]
eax, DWORD PTR [ecx]
edi
esi
eax, ebx
ebp
DWORD PTR [ecx], eax
ebx
esp, 20
; 00000014H
0
ENDP

5 .
64- MSVC 2008:
Listing 1.113: MSVC 2008
a1$ = 56
a2$ = 64
a3$ = 72
a4$ = 80
x36$1$ = 88
a5$ = 88
a6$ = 96
out1$ = 104
out2$ = 112
out3$ = 120
out4$ = 128
s1
PROC
$LN3:
mov
QWORD
mov
QWORD
mov
QWORD
mov
QWORD
push
rsi
push
rdi
push
r12
push
r13
push
r14
push
r15

PTR
PTR
PTR
PTR

[rsp+24], rbx
[rsp+32], rbp
[rsp+16], rdx
[rsp+8], rcx

126

1.20. 64
mov
mov
mov
mov
mov
mov
not
xor
not
mov
and
mov
mov
and
and
and
mov
mov
xor
mov
mov
or
not
and
mov
and
mov
mov
xor
xor
not
and
mov
xor
or
xor
and
mov
or
xor
mov
xor
and
or
not
xor
mov
xor
xor
mov
mov
mov
or
or
mov
xor
mov
mov
mov
xor
not
and
mov
and
xor
xor
not
and
mov
and
xor
mov
xor
xor
mov
mov

1.

r15, QWORD PTR a5$[rsp]


rcx, QWORD PTR a6$[rsp]
rbp, r8
r10, r9
rax, r15
rdx, rbp
rax
rdx, r9
r10
r11, rax
rax, r9
rsi, r10
QWORD PTR x36$1$[rsp], rax
r11, r8
rsi, r8
r10, r15
r13, rdx
rbx, r11
rbx, r9
r9, QWORD PTR a2$[rsp]
r12, rsi
r12, r15
r13
r13, rcx
r14, r12
r14, rcx
rax, r14
r8, r14
r8, rbx
rax, r15
rbx
rax, rdx
rdi, rax
rdi, rsi
rdi, rcx
rdi, r10
rbx, rdi
rcx, rdi
rcx, r9
rcx, rax
rax, r13
rax, QWORD PTR x36$1$[rsp]
rcx, QWORD PTR a1$[rsp]
rax, r9
rcx
rcx, rax
rax, QWORD PTR out2$[rsp]
rcx, QWORD PTR [rax]
rcx, r8
QWORD PTR [rax], rcx
rax, QWORD PTR x36$1$[rsp]
rcx, r14
rax, r8
rcx, r11
r11, r9
rcx, rdx
QWORD PTR x36$1$[rsp], rax
r8, rsi
rdx, rcx
rdx, r13
rdx
rdx, rdi
r10, rdx
r10, r9
r10, rax
r10, rbx
rbx
rbx, r9
rax, r10
rax, QWORD PTR a1$[rsp]
rbx, rax
rax, QWORD PTR out4$[rsp]
rbx, QWORD PTR [rax]
rbx, rcx
QWORD PTR [rax], rbx
rbx, QWORD PTR x36$1$[rsp]

127

1.21. C99 RESTRICT

s1

and
mov
not
and
or
mov
xor
not
and
or
mov
or
xor
mov
not
not
not
and
or
and
xor
xor
mov
not
not
and
and
and
xor
mov
not
xor
or
not
xor
mov
mov
xor
xor
xor
mov
pop
pop
pop
pop
pop
pop
ret
ENDP

1.

rbx, rbp
r9, rbx
r9
r9, rdi
r8, r11
rax, QWORD PTR out1$[rsp]
r8, r9
r9
r9, rcx
rdx, rbp
rbp, QWORD PTR [rsp+80]
r9, rsi
rbx, r12
rcx, r11
rcx
r14
r13
rcx, r9
r9, rdi
rbx, r14
r9, r15
rcx, rdx
rdx, QWORD PTR a1$[rsp]
r9
rcx
r13, r10
r9, r11
rcx, rdx
r9, rbx
rbx, QWORD PTR [rsp+72]
rcx
rcx, QWORD PTR [rax]
r9, rdx
r9
rcx, r8
QWORD PTR [rax], rcx
rax, QWORD PTR out3$[rsp]
r9, r13
r9, QWORD PTR [rax]
r9, r8
QWORD PTR [rax], r9
r15
r14
r13
r12
rdi
rsi
0

, x36 a5.
, RCX, RDX
, R8 R9 , .
, , , Itanium 128 .

1.20.2

ARM

64- ARM ARMv8.

1.21

C99 restrict

- FORTRAN, , .
void f1 (int* x, int* y, int* sum, int* product, int* sum_product, int* update_me, size_t s)
{
for (int i=0; i<s; i++)
{
sum[i]=x[i]+y[i];
product[i]=x[i]*y[i];

128

1.21. C99 RESTRICT

1.

update_me[i]=i*123; // some dummy value


sum_product[i]=sum[i]+product[i];
};
};

, : update_me
sum, product, sum_product
, ?
, , 4 :
sum[i]
product[i]
update_me[i]
sum_product[i] sum[i] product[i]
? sum[i] product[i] , . , ,
! pointer aliasing, ,
- , .
restrict C99 [12, 6.7.3/1] , , ,
.
, , restrict ,
, ,
. , ,
, restrict.
-:
void f2 (int* restrict x, int* restrict y, int* restrict sum, int* restrict product, int* restrict
sum_product,
int* restrict update_me, size_t s)
{
for (int i=0; i<s; i++)
{
sum[i]=x[i]+y[i];
product[i]=x[i]*y[i];
update_me[i]=i*123; // some dummy value
sum_product[i]=sum[i]+product[i];
};
};

:
Listing 1.114: GCC x64: f1()
f1:
push
mov
mov
mov
test
je
add
xor
mov
xor
jmp

r15 r14 r13 r12 rbp rdi rsi rbx


r13, QWORD PTR 120[rsp]
rbp, QWORD PTR 104[rsp]
r12, QWORD PTR 112[rsp]
r13, r13
.L1
r13, 1
ebx, ebx
edi, 1
r11d, r11d
.L4

mov
mov

r11, rdi
rdi, rax

lea
lea
lea

rax, 0[0+r11*4]
r10, [rcx+rax]
r14, [rdx+rax]

.L6:

.L4:

129

1.21. C99 RESTRICT

1.

lea
add
mov
add
mov
mov
imul
mov
mov
add
mov
add
lea
cmp
mov
jne

rsi, [r8+rax]
rax, r9
r15d, DWORD PTR [r10]
r15d, DWORD PTR [r14]
DWORD PTR [rsi], r15d
r10d, DWORD PTR [r10]
r10d, DWORD PTR [r14]
DWORD PTR [rax], r10d
DWORD PTR [r12+r11*4], ebx
ebx, 123
r10d, DWORD PTR [rsi]
r10d, DWORD PTR [rax]
rax, 1[rdi]
rax, r13
DWORD PTR 0[rbp+r11*4], r10d
.L6

pop
ret

rbx rsi rdi rbp r12 r13 r14 r15

; store to sum[]

; store to product[]
; store to update_me[]
; reload sum[i]
; reload product[i]

; store to sum_product[]

.L1:

Listing 1.115: GCC x64: f2()


f2:
push
mov
mov
mov
test
je
add
xor
mov
xor
jmp

r13 r12 rbp rdi rsi rbx


r13, QWORD PTR 104[rsp]
rbp, QWORD PTR 88[rsp]
r12, QWORD PTR 96[rsp]
r13, r13
.L7
r13, 1
r10d, r10d
edi, 1
eax, eax
.L10

mov
mov

rax, rdi
rdi, r11

mov
mov
mov
add
lea
imul
mov
mov
add
mov
lea
cmp
jne

esi, DWORD PTR [rcx+rax*4]


r11d, DWORD PTR [rdx+rax*4]
DWORD PTR [r12+rax*4], r10d
r10d, 123
ebx, [rsi+r11]
r11d, esi
DWORD PTR [r8+rax*4], ebx
DWORD PTR [r9+rax*4], r11d
r11d, ebx
DWORD PTR 0[rbp+rax*4], r11d
r11, 1[rdi]
r11, r13
.L11

pop
ret

rbx rsi rdi rbp r12 r13

.L11:

.L10:

; store to update_me[]

; store to sum[]
; store to product[]
; store to sum_product[]

.L7:

f1() f2() : f1(), sum[i] product[i] , f2() , ,


, sum[i] product[i]
, , . ,
.
?
, .
FORTRAN. , , , ,
restrict, FORTRAN
.
? .
, . /HPC1
, , , FORTRAN, [16].
134

High-Performace Computing

130

1.22. INLINE-
1.
, , .

1.22

Inline-

Inline- , ,
.
Listing 1.116:
#include <stdio.h>
int celsius_to_fahrenheit (int celsius)
{
return celsius * 9 / 5 + 32;
};
int main(int argc, char *argv[])
{
int celsius=atol(argv[1]);
printf ("%d\n", celsius_to_fahrenheit (celsius));
};

... , , GCC (-O3), :


Listing 1.117: GCC 4.8.1 -O3
_main:
push
mov
and
sub
call
mov
mov
mov
call
mov
mov
lea
mov
imul
sar
sar
sub
add
mov
call
leave
ret

ebp
ebp, esp
esp, -16
esp, 16
___main
eax, DWORD PTR [ebp+12]
eax, DWORD PTR [eax+4]
DWORD PTR [esp], eax
_atol
edx, 1717986919
DWORD PTR [esp], OFFSET FLAT:LC2 ; "%d\12\0"
ecx, [eax+eax*8]
eax, ecx
edx
ecx, 31
edx
edx, ecx
edx, 32
DWORD PTR [esp+4], edx
_printf

( (1.12).)
, - printf(). ?
- .
, - inline -, ,
, - .
- strcpy(), strcmp(), .
Listing 1.118:
bool is_bool (char *s)
{
if (strcmp (s,
return
if (strcmp (s,
return

"true")==0)
true;
"false")==0)
false;

assert(0);
};

131

1.22. INLINE-

1.
Listing 1.119: GCC 4.8.1 -O3

_is_bool:
push
edi
mov
ecx, 5
push
esi
mov
edi, OFFSET FLAT:LC0 ; "true\0"
sub
esp, 20
mov
esi, DWORD PTR [esp+32]
repz cmpsb
je
L3
mov
esi, DWORD PTR [esp+32]
mov
ecx, 6
mov
edi, OFFSET FLAT:LC1 ; "false\0"
repz cmpsb
seta
cl
setb
dl
xor
eax, eax
cmp
cl, dl
jne
L8
add
esp, 20
pop
esi
pop
edi
ret

strcmp() MSVC:
Listing 1.120: MSVC
mov
cmp
jnz
test
jz
mov
cmp
jnz
add
add
test
jnz

dl, [eax]
dl, [ecx]
short loc_10027FA0
dl, dl
short loc_10027F9C
dl, [eax+1]
dl, [ecx+1]
short loc_10027FA0
eax, 2
ecx, 2
dl, dl
short loc_10027F80

loc_10027F9C:

; CODE XREF: f1+448


xor
eax, eax
jmp
short loc_10027FA5
; --------------------------------------------------------------------------loc_10027FA0:

; CODE XREF: f1+444


; f1+450
sbb
sbb

eax, eax
eax, 0FFFFFFFFh

IDA
inline-: https://github.com/yurichev/IDA_scripts.

132

2. ++

++
2.1

2.1.1


++ .
, :
#include <stdio.h>
class c
{
private:
int v1;
int v2;
public:
c() // default ctor
{
v1=667;
v2=999;
};
c(int a, int b) // ctor
{
v1=a;
v2=b;
};
void dump()
{
printf ("%d; %d\n", v1, v2);
};
};
int main()
{
class c c1;
class c c2(5,6);
c1.dump();
c2.dump();
return 0;
};

main() :
_c2$ = -16
; size = 8
_c1$ = -8
; size = 8
_main
PROC
push
ebp
mov
ebp, esp
sub
esp, 16
; 00000010H
lea
ecx, DWORD PTR _c1$[ebp]
call
??0c@@QAE@XZ
; c::c

133

2.1.

2. ++

push
6
push
5
lea
ecx, DWORD PTR _c2$[ebp]
call
??0c@@QAE@HH@Z
; c::c
lea
ecx, DWORD PTR _c1$[ebp]
call
?dump@c@@QAEXXZ
; c::dump
lea
ecx, DWORD PTR _c2$[ebp]
call
?dump@c@@QAEXXZ
; c::dump
xor
eax, eax
mov
esp, ebp
pop
ebp
ret
0
_main
ENDP

. c 8 , ,
.
c1 ??0c@@QAE@XZ. c2 ??0c@@QAE@HH@Z .
(this ++) ECX. thiscall (2.1.1)
.
, MSVC ECX. ,
, , ( GCC).
? name mangling1 .
++, ,
. , .
Name mangling + +
ASCII-, . 2 , DLL ( / DLL),
++ 3 .
dump().
:
_this$ = -4
; size = 4
??0c@@QAE@XZ PROC
; c::c, COMDAT
; _this$ = ecx
push
ebp
mov
ebp, esp
push
ecx
mov
DWORD PTR _this$[ebp], ecx
mov
eax, DWORD PTR _this$[ebp]
mov
DWORD PTR [eax], 667
; 0000029bH
mov
ecx, DWORD PTR _this$[ebp]
mov
DWORD PTR [ecx+4], 999
; 000003e7H
mov
eax, DWORD PTR _this$[ebp]
mov
esp, ebp
pop
ebp
ret
0
??0c@@QAE@XZ ENDP
; c::c
_this$ = -4
; size = 4
_a$ = 8
; size = 4
_b$ = 12
; size = 4
??0c@@QAE@HH@Z PROC
; c::c, COMDAT
; _this$ = ecx
push
ebp
mov
ebp, esp
push
ecx
mov
DWORD PTR _this$[ebp], ecx
mov
eax, DWORD PTR _this$[ebp]
mov
ecx, DWORD PTR _a$[ebp]
mov
DWORD PTR [eax], ecx
mov
edx, DWORD PTR _this$[ebp]
mov
eax, DWORD PTR _b$[ebp]
mov
DWORD PTR [edx+4], eax
mov
eax, DWORD PTR _this$[ebp]
1

Wikipedia: Name mangling


linker
3
-
2

134

2.1.
mov
esp, ebp
pop
ebp
ret
8
??0c@@QAE@HH@Z ENDP

2. ++

; c::c

, ECX,
, .
++ [13, 12.1] . ,
, , .., this.
dump():
_this$ = -4
; size = 4
?dump@c@@QAEXXZ PROC
; c::dump, COMDAT
; _this$ = ecx
push
ebp
mov
ebp, esp
push
ecx
mov
DWORD PTR _this$[ebp], ecx
mov
eax, DWORD PTR _this$[ebp]
mov
ecx, DWORD PTR [eax+4]
push
ecx
mov
edx, DWORD PTR _this$[ebp]
mov
eax, DWORD PTR [edx]
push
eax
push
OFFSET ??_C@_07NJBDCIEC@?$CFd?$DL?5?$CFd?6?$AA@
call
_printf
add
esp, 12
; 0000000cH
mov
esp, ebp
pop
ebp
ret
0
?dump@c@@QAEXXZ ENDP
; c::dump

, dump() int ECX,


printf().
(/Ox), :
??0c@@QAE@XZ PROC
;
; _this$ = ecx
mov
eax, ecx
mov
DWORD PTR [eax], 667
mov
DWORD PTR [eax+4], 999
ret
0
??0c@@QAE@XZ ENDP

c::c, COMDAT

; 0000029bH
; 000003e7H
; c::c

_a$ = 8
; size = 4
_b$ = 12
; size = 4
??0c@@QAE@HH@Z PROC
; c::c, COMDAT
; _this$ = ecx
mov
edx, DWORD PTR _b$[esp-4]
mov
eax, ecx
mov
ecx, DWORD PTR _a$[esp-4]
mov
DWORD PTR [eax], ecx
mov
DWORD PTR [eax+4], edx
ret
8
??0c@@QAE@HH@Z ENDP
; c::c
?dump@c@@QAEXXZ PROC
; c::dump, COMDAT
; _this$ = ecx
mov
eax, DWORD PTR [ecx+4]
mov
ecx, DWORD PTR [ecx]
push
eax
push
ecx
push
OFFSET ??_C@_07NJBDCIEC@?$CFd?$DL?5?$CFd?6?$AA@
call
_printf
add
esp, 12
; 0000000cH
ret
0
?dump@c@@QAEXXZ ENDP
; c::dump

. , main(),
, add esp, X.
, RET RET 8.

135

2.1.
2. ++
thiscall (2.1.1), , stdcall (3.4.2) (
), . ret
X X ESP, .
. (3.4).
, , , ,
++.
GCC GCC 4.4.1 , .
main

public main
proc near

var_20
var_1C
var_18
var_10
var_8

=
=
=
=
=

main

push
mov
and
sub
lea
mov
call
mov
mov
lea
mov
call
lea
mov
call
lea
mov
call
mov
leave
retn
endp

dword
dword
dword
dword
dword

ptr
ptr
ptr
ptr
ptr

; DATA XREF: _start+17


-20h
-1Ch
-18h
-10h
-8

ebp
ebp, esp
esp, 0FFFFFFF0h
esp, 20h
eax, [esp+20h+var_8]
[esp+20h+var_20], eax
_ZN1cC1Ev
[esp+20h+var_18], 6
[esp+20h+var_1C], 5
eax, [esp+20h+var_10]
[esp+20h+var_20], eax
_ZN1cC1Eii
eax, [esp+20h+var_8]
[esp+20h+var_20], eax
_ZN1c4dumpEv
eax, [esp+20h+var_10]
[esp+20h+var_20], eax
_ZN1c4dumpEv
eax, 0

name mangling GNU4 . -,


, .
:
_ZN1cC1Ev

public _ZN1cC1Ev ; weak


proc near
; CODE XREF: main+10

arg_0

= dword ptr

_ZN1cC1Ev

push
mov
mov
mov
mov
mov
pop
retn
endp

ebp
ebp, esp
eax, [ebp+arg_0]
dword ptr [eax], 667
eax, [ebp+arg_0]
dword ptr [eax+4], 999
ebp

( ) .
:
_ZN1cC1Eii

public _ZN1cC1Eii
proc near

arg_0
arg_4
arg_8

= dword ptr
= dword ptr
= dword ptr

8
0Ch
10h

name mangling : http://www.agner.org/optimize/calling_conventions.pdf

136

2.1.

_ZN1cC1Eii

2. ++
push
mov
mov
mov
mov
mov
mov
mov
pop
retn
endp

ebp
ebp, esp
eax, [ebp+arg_0]
edx, [ebp+arg_4]
[eax], edx
eax, [ebp+arg_0]
edx, [ebp+arg_8]
[eax+4], edx
ebp

, :
void ZN1cC1Eii (int *obj, int a, int b)
{
*obj=a;
*(obj+1)=b;
};

. . . , , .
dump():
_ZN1c4dumpEv

public _ZN1c4dumpEv
proc near

var_18
var_14
var_10
arg_0

=
=
=
=

_ZN1c4dumpEv

push
mov
sub
mov
mov
mov
mov
mov
mov
mov
call
leave
retn
endp

dword
dword
dword
dword

ptr -18h
ptr -14h
ptr -10h
ptr 8
ebp
ebp, esp
esp, 18h
eax, [ebp+arg_0]
edx, [eax+4]
eax, [ebp+arg_0]
eax, [eax]
[esp+18h+var_10], edx
[esp+18h+var_14], eax
[esp+18h+var_18], offset aDD ; "%d; %d\n"
_printf

,
5 (this).
, , MSVC GCC
(name mangling) ( ECX
).

2.1.2

,
.
:
#include <stdio.h>
class object
{
public:
int color;
object() { };
object (int color) { this->color=color; };
void print_color() { printf ("color=%d\n", color); };
};

137

2.1.

2. ++

class box : public object


{
private:
int width, height, depth;
public:
box(int color, int width, int height, int depth)
{
this->color=color;
this->width=width;
this->height=height;
this->depth=depth;
};
void dump()
{
printf ("this is box. color=%d, width=%d, height=%d, depth=%d\n", color, width, height, depth)
;
};
};
class sphere : public object
{
private:
int radius;
public:
sphere(int color, int radius)
{
this->color=color;
this->radius=radius;
};
void dump()
{
printf ("this is sphere. color=%d, radius=%d\n", color, radius);
};
};
int main()
{
box b(1, 10, 20, 30);
sphere s(2, 40);
b.print_color();
s.print_color();
b.dump();
s.dump();
return 0;
};

/ dump(), object::print_color(),
- ( 32- ).
, dump() MSVC 2008 /Ox /Ob0 6
Listing 2.1: MSVC 2008 /Ob0
??_C@_09GCEDOLPA@color?$DN?$CFd?6?$AA@ DB color=%d, 0aH, 00H ; string
?print_color@object@@QAEXXZ PROC
; object::print_color, COMDAT
; _this$ = ecx
mov
eax, DWORD PTR [ecx]
push
eax
; color=%d, 0aH, 00H
push
OFFSET ??_C@_09GCEDOLPA@color?$DN?$CFd?6?$AA@
call
_printf
add
esp, 8
ret
0
?print_color@object@@QAEXXZ ENDP
; object::print_color

Listing 2.2: MSVC 2008 /Ob0


?dump@box@@QAEXXZ PROC
; _this$ = ecx

; box::dump, COMDAT

6
/Ob0 inline expansion, /

138

2.1.
mov
mov
push
mov
mov
push
push
push

2. ++
eax,
edx,
eax
eax,
ecx,
edx
eax
ecx

DWORD PTR [ecx+12]


DWORD PTR [ecx+8]
DWORD PTR [ecx+4]
DWORD PTR [ecx]

; this is box. color=%d, width=%d, height=%d, depth=%d, 0aH, 00H ; string


push
OFFSET ??_C@_0DG@NCNGAADL@this?5is?5box?4?5color?$DN?$CFd?0?5width?$DN?$CFd?0@
call
_printf
add
esp, 20
; 00000014H
ret
0
?dump@box@@QAEXXZ ENDP
; box::dump

Listing 2.3: MSVC 2008 /Ob0


?dump@sphere@@QAEXXZ PROC
; _this$ = ecx
mov
eax, DWORD PTR [ecx+4]
mov
ecx, DWORD PTR [ecx]
push
eax
push
ecx

; sphere::dump, COMDAT

; this is sphere. color=%d, radius=%d, 0aH, 00H


push
OFFSET ??_C@_0CF@EFEDJLDC@this?5is?5sphere?4?5color?$DN?$CFd?0?5radius@
call
_printf
add
esp, 12
; 0000000cH
ret
0
?dump@sphere@@QAEXXZ ENDP
; sphere::dump

, :
( object)

+0x0

int color

+0x0
+0x4
+0x8
+0xC

int color
int width
int height
int depth

+0x0
+0x4

int color
int radius

( )
box:

sphere:

main():
Listing 2.4: MSVC 2008 /Ob0
PUBLIC _main
_TEXT
SEGMENT
_s$ = -24
_b$ = -16
_main
PROC
sub
push
push
push
push
lea
call

; size = 8
; size = 16
esp, 24
30
20
10
1
ecx, DWORD PTR _b$[esp+40]
??0box@@QAE@HHHH@Z

;
;
;
;

00000018H
0000001eH
00000014H
0000000aH

; box::box

139

2.1.

_main

push
push
lea
call
lea
call
lea
call
lea
call
lea
call
xor
add
ret
ENDP

2. ++
40
2
ecx, DWORD PTR _s$[esp+32]
??0sphere@@QAE@HH@Z
ecx, DWORD PTR _b$[esp+24]
?print_color@object@@QAEXXZ
ecx, DWORD PTR _s$[esp+24]
?print_color@object@@QAEXXZ
ecx, DWORD PTR _b$[esp+24]
?dump@box@@QAEXXZ
ecx, DWORD PTR _s$[esp+24]
?dump@sphere@@QAEXXZ
eax, eax
esp, 24
0

; 00000028H

; sphere::sphere
; object::print_color
; object::print_color
; box::dump
; sphere::dump
; 00000018H

,
.
object::print_color() , this
box sphere, box sphere,
color ( 0x0).
object::print_color() ,
, ,
.
- box, ,
depth, box .
, box::dump() color/width/height/depth
.
GCC , this (,
, , ECX).

2.1.3

private , ,
, .
, - , ,
?
, .
:
#include <stdio.h>
class box
{
private:
int color, width, height, depth;
public:
box(int color, int width, int height, int depth)
{
this->color=color;
this->width=width;
this->height=height;
this->depth=depth;
};
void dump()
{
printf ("this is box. color=%d, width=%d, height=%d, depth=%d\n", color, width, height, depth)
;
};
};

MSVC 2008 /Ox /Ob0 box::dump():


?dump@box@@QAEXXZ PROC
; _this$ = ecx
mov
eax, DWORD PTR [ecx+12]

; box::dump, COMDAT

140

2.1.

2. ++

mov
edx, DWORD PTR [ecx+8]
push
eax
mov
eax, DWORD PTR [ecx+4]
mov
ecx, DWORD PTR [ecx]
push
edx
push
eax
push
ecx
; this is box. color=%d, width=%d, height=%d, depth=%d, 0aH, 00H
push
OFFSET ??_C@_0DG@NCNGAADL@this?5is?5box?4?5color?$DN?$CFd?0?5width?$DN?$CFd?0@
call
_printf
add
esp, 20
; 00000014H
ret
0
?dump@box@@QAEXXZ ENDP
; box::dump

+0x0
+0x4
+0x8
+0xC

int color
int width
int height
int depth

, , ,
?
hack_oop_encapsulation(),
, :
void hack_oop_encapsulation(class box * o)
{
o->width=1; // that code cant be compiled: "error C2248: box::width : cannot access private member
declared in class box"
};

, box int, int-, .


void hack_oop_encapsulation(class box * o)
{
unsigned int *ptr_to_object=reinterpret_cast<unsigned int*>(o);
ptr_to_object[1]=123;
};

, int-
123 int:
?hack_oop_encapsulation@@YAXPAVbox@@@Z PROC
mov
eax, DWORD PTR _o$[esp-4]
mov
DWORD PTR [eax+4], 123
ret
0
?hack_oop_encapsulation@@YAXPAVbox@@@Z ENDP

; hack_oop_encapsulation
; 0000007bH
; hack_oop_encapsulation

, :
int main()
{
box b(1, 10, 20, 30);
b.dump();
hack_oop_encapsulation(&b);
b.dump();
return 0;
};

:
this is box. color=1, width=10, height=20, depth=30
this is box. color=1, width=123, height=20, depth=30

141

2.1.
2. ++
, . ++
, ,
.

2.1.4

.
:
#include <stdio.h>
class box
{
public:
int width, height, depth;
box() { };
box(int width, int height, int depth)
{
this->width=width;
this->height=height;
this->depth=depth;
};
void dump()
{
printf ("this is box. width=%d, height=%d, depth=%d\n", width, height, depth);
};
int get_volume()
{
return width * height * depth;
};
};
class solid_object
{
public:
int density;
solid_object() { };
solid_object(int density)
{
this->density=density;
};
int get_density()
{
return density;
};
void dump()
{
printf ("this is solid_object. density=%d\n", density);
};
};
class solid_box: box, solid_object
{
public:
solid_box (int width, int height, int depth, int density)
{
this->width=width;
this->height=height;
this->depth=depth;
this->density=density;
};
void dump()
{
printf ("this is solid_box. width=%d, height=%d, depth=%d, density=%d\n", width, height, depth
, density);
};
int get_weight() { return get_volume() * get_density(); };
};
int main()
{
box b(10, 20, 30);
solid_object so(100);
solid_box sb(10, 20, 30, 3);

142

2.1.

2. ++

b.dump();
so.dump();
sb.dump();
printf ("%d\n", sb.get_weight());
return 0;
};

MSVC 2008 /Ox /Ob0 box::dump(),


solid_object::dump(), solid_box::dump():
Listing 2.5: MSVC 2008 /Ob0
?dump@box@@QAEXXZ PROC
; box::dump, COMDAT
; _this$ = ecx
mov
eax, DWORD PTR [ecx+8]
mov
edx, DWORD PTR [ecx+4]
push
eax
mov
eax, DWORD PTR [ecx]
push
edx
push
eax
; this is box. width=%d, height=%d, depth=%d, 0aH, 00H
push
OFFSET ??_C@_0CM@DIKPHDFI@this?5is?5box?4?5width?$DN?$CFd?0?5height?$DN?$CFd@
call
_printf
add
esp, 16
; 00000010H
ret
0
?dump@box@@QAEXXZ ENDP
; box::dump

Listing 2.6: MSVC 2008 /Ob0


?dump@solid_object@@QAEXXZ PROC
; solid_object::dump, COMDAT
; _this$ = ecx
mov
eax, DWORD PTR [ecx]
push
eax
; this is solid_object. density=%d, 0aH
push
OFFSET ??_C@_0CC@KICFJINL@this?5is?5solid_object?4?5density?$DN?$CFd@
call
_printf
add
esp, 8
ret
0
?dump@solid_object@@QAEXXZ ENDP
; solid_object::dump

Listing 2.7: MSVC 2008 /Ob0


?dump@solid_box@@QAEXXZ PROC
; solid_box::dump, COMDAT
; _this$ = ecx
mov
eax, DWORD PTR [ecx+12]
mov
edx, DWORD PTR [ecx+8]
push
eax
mov
eax, DWORD PTR [ecx+4]
mov
ecx, DWORD PTR [ecx]
push
edx
push
eax
push
ecx
; this is solid_box. width=%d, height=%d, depth=%d, density=%d, 0aH
push
OFFSET ??_C@_0DO@HNCNIHNN@this?5is?5solid_box?4?5width?$DN?$CFd?0?5hei@
call
_printf
add
esp, 20
; 00000014H
ret
0
?dump@solid_box@@QAEXXZ ENDP
; solid_box::dump

, :
box:

+0x0
+0x4
+0x8

width
height
depth

solid_object:

143

2.1.

2. ++

+0x0

density

, solid_box :
solid_box:

+0x0
+0x4
+0x8
+0xC

width
height
depth
density

box::get_volume() solid_object::get_density() :
Listing 2.8: MSVC 2008 /Ob0
?get_volume@box@@QAEHXZ PROC
; _this$ = ecx
mov
eax, DWORD PTR [ecx+8]
imul
eax, DWORD PTR [ecx+4]
imul
eax, DWORD PTR [ecx]
ret
0
?get_volume@box@@QAEHXZ ENDP

; box::get_volume, COMDAT

; box::get_volume

Listing 2.9: MSVC 2008 /Ob0


?get_density@solid_object@@QAEHXZ PROC
; _this$ = ecx
mov
eax, DWORD PTR [ecx]
ret
0
?get_density@solid_object@@QAEHXZ ENDP

; solid_object::get_density, COMDAT

; solid_object::get_density

solid_box::get_weight() :
Listing 2.10: MSVC 2008 /Ob0
?get_weight@solid_box@@QAEHXZ PROC
; _this$ = ecx
push
esi
mov
esi, ecx
push
edi
lea
ecx, DWORD PTR [esi+12]
call
?get_density@solid_object@@QAEHXZ
mov
ecx, esi
mov
edi, eax
call
?get_volume@box@@QAEHXZ
imul
eax, edi
pop
edi
pop
esi
ret
0
?get_weight@solid_box@@QAEHXZ ENDP

; solid_box::get_weight, COMDAT

; solid_object::get_density

; box::get_volume

; solid_box::get_weight

get_weight() , get_volume()
this, get_density(), this 12 ( 0xC ), ,
solid_box, solid_object.
, solid_object::get_density() solid_object,
box::get_volume() , ,
box.
, , -
, . .

2.1.5

144

2.1.

2. ++

#include <stdio.h>
class object
{
public:
int color;
object() { };
object (int color) { this->color=color; };
virtual void dump()
{
printf ("color=%d\n", color);
};
};
class box : public object
{
private:
int width, height, depth;
public:
box(int color, int width, int height, int depth)
{
this->color=color;
this->width=width;
this->height=height;
this->depth=depth;
};
void dump()
{
printf ("this is box. color=%d, width=%d, height=%d, depth=%d\n", color, width, height, depth)
;
};
};
class sphere : public object
{
private:
int radius;
public:
sphere(int color, int radius)
{
this->color=color;
this->radius=radius;
};
void dump()
{
printf ("this is sphere. color=%d, radius=%d\n", color, radius);
};
};
int main()
{
box b(1, 10, 20, 30);
sphere s(2, 40);
object *o1=&b;
object *o2=&s;
o1->dump();
o2->dump();
return 0;
};

object dump(), - box


sphere.
- , , , main()
, dump(), - ,
.
MSVC 2008 /Ox /Ob0 main():
_s$ = -32
_b$ = -20
_main
PROC
sub
push

; size = 12
; size = 20
esp, 32
30

; 00000020H
; 0000001eH

145

2.1.

_main

push
push
push
lea
call
push
push
lea
call
mov
mov
lea
call
mov
mov
lea
call
xor
add
ret
ENDP

2. ++
20
10
1
ecx, DWORD PTR _b$[esp+48]
??0box@@QAE@HHHH@Z
40
2
ecx, DWORD PTR _s$[esp+40]
??0sphere@@QAE@HH@Z
eax, DWORD PTR _b$[esp+32]
edx, DWORD PTR [eax]
ecx, DWORD PTR _b$[esp+32]
edx
eax, DWORD PTR _s$[esp+32]
edx, DWORD PTR [eax]
ecx, DWORD PTR _s$[esp+32]
edx
eax, eax
esp, 32
0

; 00000014H
; 0000000aH

; box::box
; 00000028H

; sphere::sphere

; 00000020H

dump() - ().
-? , : main()
. 7
box:
??_R0?AVbox@@@8 DD FLAT:??_7type_info@@6B@
DD
00H
DB
.?AVbox@@, 00H

; box RTTI Type Descriptor

??_R1A@?0A@EA@box@@8 DD FLAT:??_R0?AVbox@@@8
DD
01H
DD
00H
DD
0ffffffffH
DD
00H
DD
040H
DD
FLAT:??_R3box@@8

; box::RTTI Base Class Descriptor at (0,-1,0,64)

??_R2box@@8 DD
DD

FLAT:??_R1A@?0A@EA@box@@8
FLAT:??_R1A@?0A@EA@object@@8

; box::RTTI Base Class Array

??_R3box@@8 DD
DD
DD
DD

00H
00H
02H
FLAT:??_R2box@@8

; box::RTTI Class Hierarchy Descriptor

??_R4box@@6B@ DD 00H
DD
00H
DD
00H
DD
FLAT:??_R0?AVbox@@@8
DD
FLAT:??_R3box@@8

; box::RTTI Complete Object Locator

??_7box@@6B@ DD FLAT:??_R4box@@6B@
DD
FLAT:?dump@box@@UAEXXZ

; box::vftable

_color$ = 8
_width$ = 12
_height$ = 16
_depth$ = 20
??0box@@QAE@HHHH@Z PROC
; _this$ = ecx
push
esi
mov
esi, ecx
call
??0object@@QAE@XZ
mov
eax, DWORD PTR _color$[esp]
mov
ecx, DWORD PTR _width$[esp]
mov
edx, DWORD PTR _height$[esp]
mov
DWORD PTR [esi+4], eax
mov
eax, DWORD PTR _depth$[esp]
mov
DWORD PTR [esi+16], eax
mov
DWORD PTR [esi], OFFSET ??_7box@@6B@
mov
DWORD PTR [esi+8], ecx

;
;
;
;
;

size = 4
size = 4
size = 4
size = 4
box::box, COMDAT

; object::object

:(1.18)

146

2.2. OSTREAM

2. ++

mov
DWORD PTR [esi+12], edx
mov
eax, esi
pop
esi
ret
16
??0box@@QAE@HHHH@Z ENDP

; 00000010H
; box::box

:
box::vftable ( MSVC).
box::RTTI Complete Object Locator
box::dump(). , RTTI8 .
, RTTI . ,
RTTI- , dynamic_cast
typeid ++. . , object object::dump()
,
.
, - , , .
GCC RTTI- - .

2.2

ostream

hello world, ostream:


#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
}

++, .
ostream. operator ostream:
Listing 2.11: MSVC 2012 (reduced listing)
$SG37112 DB

Hello, world!, 0aH, 00H

_main

PROC
push
OFFSET $SG37112
push
OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call
??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add
esp, 8
xor
eax, eax
ret
0
_main
ENDP

:
#include <iostream>
int main()
{
std::cout << "Hello, " << "world!\n";
}

, ++, operator ostream . :


Listing 2.12: MSVC 2012
$SG37112 DB
$SG37113 DB

world!, 0aH, 00H


Hello, , 00H

Run-time type information

147

2.3. REFERENCES

2. ++

_main

PROC
push
OFFSET $SG37113 ; Hello,
push
OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call
??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add
esp, 8
push
OFFSET $SG37112 ; world!
push
eax
; result of previous function
call
??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add
esp, 8

_main

xor
ret
ENDP

eax, eax
0

operator f(), :
f(f(std::cout, "Hello, "), "world!")

GCC MSVC.

2.3

References

References ++ (1.7), (safe), ,


[13, 8.3.2]. , reference
NULL [6, 8.6]. , reference ,
(reseat) [6, 8.5].
(1.7) reference :
void f2 (int x, int y, int & sum, int & product)
{
sum=x+y;
product=x*y;
};

(1.7):
Listing 2.13: MSVC 2010
_x$ = 8
_y$ = 12
_sum$ = 16
_product$ = 20
?f2@@YAXHHAAH0@Z PROC
mov
ecx, DWORD PTR _y$[esp-4]
mov
eax, DWORD PTR _x$[esp-4]
lea
edx, DWORD PTR [eax+ecx]
imul eax, ecx
mov ecx, DWORD PTR _product$[esp-4]
push esi
mov
esi, DWORD PTR _sum$[esp]
mov
DWORD PTR [esi], edx
mov
DWORD PTR [ecx], eax
pop
esi
ret
0
?f2@@YAXHHAAH0@Z ENDP

;
;
;
;
;

size
size
size
size
f2

=
=
=
=

4
4
4
4

; f2

( ++ , : 2.1.1.)

2.4

STL

N.B.: 32- . x64- .

148

2.4. STL

2.4.1

2. ++

std::string


( [29, 2.2])
, ( - [29, 2.2.1])
. :
-
ASCIIZ9 -.
++ ( [13]) , std::string,
, .
, std::string (, , QString Qt), ,
: char wchar_t.
, std::string
MSVC GCC .
MSVC MSVC, (
16- ).
16 + 4 + 4 = 24
32- 16 + 8 + 8 = 32 64-, 16- ,
.
Listing 2.14: MSVC
#include <string>
#include <stdio.h>
struct std_string
{
union
{
char buf[16];
char* ptr;
} u;
size_t size;
// AKA Mysize in MSVC
size_t capacity; // AKA Myres in MSVC
};
void dump_std_string(std::string s)
{
struct std_string *p=(struct std_string*)&s;
printf ("[%s] size:%d capacity:%d\n", p->size>16 ? p->u.ptr : p->u.buf, p->size, p->capacity);
};
int main()
{
std::string s1="short string";
std::string s2="string longer that 16 bytes";
dump_std_string(s1);
dump_std_string(s2);
// that works without using c_str()
printf ("%s\n", &s1);
printf ("%s\n", s2);
};

, .
:
16- , .
, . , Microsoft
16 .
- main(): c_str(), ,
, !
9

ASCII Zero (ASCII- )

149

2.4. STL
2. ++
.
16- std::string (
) . printf()
.
( 16- ) : ( ), c_str().
. :
16- , .
GCC GCC reference count.
, std::string GCC ,
. libstdc++-v3\include\bits\basic_string.h
:
*
*
*
*
*

The reason you want _M_data pointing to the character %array and
not the _Rep is so that the debugger can see the string
contents. (Probably we should add a non-inline member to get
the _Rep for the debugger to use, so users can check the actual
string length.)

basic_string.h
:
Listing 2.15: GCC
#include <string>
#include <stdio.h>
struct std_string
{
size_t length;
size_t capacity;
size_t refcount;
};
void dump_std_string(std::string s)
{
char *p1=*(char**)&s; // GCC type checking workaround
struct std_string *p2=(struct std_string*)(p1-sizeof(struct std_string));
printf ("[%s] size:%d capacity:%d\n", p1, p2->length, p2->capacity);
};
int main()
{
std::string s1="short string";
std::string s2="string longer that 16 bytes";
dump_std_string(s1);
dump_std_string(s2);
// GCC type checking workaround:
printf ("%s\n", *(char**)&s1);
printf ("%s\n", *(char**)&s2);
};

, , -
GCC, , printf() c_str().

#include <string>
#include <stdio.h>
int main()
{
std::string s1="Hello, ";
std::string s2="world!\n";
std::string s3=s1+s2;

150

2.4. STL

2. ++

printf ("%s\n", s3.c_str());


}

Listing 2.16: MSVC 2012


$SG39512 DB
$SG39514 DB
$SG39581 DB

Hello, , 00H
world!, 0aH, 00H
%s, 0aH, 00H

_s2$ = -72
_s3$ = -48
_s1$ = -24
_main
PROC
sub

; size = 24
; size = 24
; size = 24

esp, 72

; 00000048H

push
7
push
OFFSET $SG39512
lea
ecx, DWORD PTR _s1$[esp+80]
mov
DWORD PTR _s1$[esp+100], 15
; 0000000fH
mov
DWORD PTR _s1$[esp+96], 0
mov
BYTE PTR _s1$[esp+80], 0
call
?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std
::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign
push
7
push
OFFSET $SG39514
lea
ecx, DWORD PTR _s2$[esp+80]
mov
DWORD PTR _s2$[esp+100], 15
; 0000000fH
mov
DWORD PTR _s2$[esp+96], 0
mov
BYTE PTR _s2$[esp+80], 0
call
?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std
::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign
lea
eax, DWORD PTR _s2$[esp+72]
push
eax
lea
eax, DWORD PTR _s1$[esp+76]
push
eax
lea
eax, DWORD PTR _s3$[esp+80]
push
eax
call
??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?
$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z ; std::operator+<char,std::char_traits<char>,std::
allocator<char> >
; inlined c_str() method:
cmp
DWORD PTR _s3$[esp+104], 16
lea
eax, DWORD PTR _s3$[esp+84]
cmovae eax, DWORD PTR _s3$[esp+84]
push
push
call
add
cmp
jb
push
call
add
$LN119@main:
cmp
mov
mov
mov
jb
push
call
add
$LN151@main:
cmp
mov
mov
mov
jb
push

; 00000010H

eax
OFFSET $SG39581
_printf
esp, 20

; 00000014H

DWORD PTR _s3$[esp+92], 16


SHORT $LN119@main
DWORD PTR _s3$[esp+72]
??3@YAXPAX@Z
esp, 4

; 00000010H

DWORD PTR _s2$[esp+92], 16


DWORD PTR _s3$[esp+92], 15
DWORD PTR _s3$[esp+88], 0
BYTE PTR _s3$[esp+72], 0
SHORT $LN151@main
DWORD PTR _s2$[esp+72]
??3@YAXPAX@Z
esp, 4

; 00000010H
; 0000000fH

DWORD PTR _s1$[esp+92], 16


DWORD PTR _s2$[esp+92], 15
DWORD PTR _s2$[esp+88], 0
BYTE PTR _s2$[esp+72], 0
SHORT $LN195@main
DWORD PTR _s1$[esp+72]

; 00000010H
; 0000000fH

; operator delete

; operator delete

151

2.4. STL
call
add
$LN195@main:
xor
add
ret
_main
ENDP

2. ++
??3@YAXPAX@Z
esp, 4

; operator delete

eax, eax
esp, 72
0

; 00000048H

, : - ,
? ASCIIZ-,
, , assign, s1 s2.
operator+, s3.
c_str() ,
: 16- , EAX
, , .
, , 16-
: . , std::string
, -.
`
-
.
GCC (- GCC, ,
):
Listing 2.17: GCC 4.8.1
.LC0:
.string "Hello, "
.LC1:
.string "world!\n"
main:
push
mov
push
push
push
and
sub
lea
lea
mov
lea
mov
mov

ebp
ebp, esp
edi
esi
ebx
esp, -16
esp, 32
ebx, [esp+28]
edi, [esp+20]
DWORD PTR [esp+8], ebx
esi, [esp+24]
DWORD PTR [esp+4], OFFSET FLAT:.LC0
DWORD PTR [esp], edi

call

_ZNSsC1EPKcRKSaIcE

mov
mov
mov

DWORD PTR [esp+8], ebx


DWORD PTR [esp+4], OFFSET FLAT:.LC1
DWORD PTR [esp], esi

call

_ZNSsC1EPKcRKSaIcE

mov
mov

DWORD PTR [esp+4], edi


DWORD PTR [esp], ebx

call

_ZNSsC1ERKSs

mov
mov

DWORD PTR [esp+4], esi


DWORD PTR [esp], ebx

call

_ZNSs6appendERKSs

; inlined c_str():
mov
eax, DWORD PTR [esp+28]
mov
DWORD PTR [esp], eax
call

puts

mov
lea
mov
sub

eax, DWORD PTR [esp+28]


ebx, [esp+19]
DWORD PTR [esp+4], ebx
eax, 12

152

2.4. STL
mov
call
mov
mov
sub
mov
call
mov
mov
sub
mov
call
lea
xor
pop
pop
pop
pop
ret

2. ++
DWORD PTR [esp], eax
_ZNSs4_Rep10_M_disposeERKSaIcE
eax, DWORD PTR [esp+24]
DWORD PTR [esp+4], ebx
eax, 12
DWORD PTR [esp], eax
_ZNSs4_Rep10_M_disposeERKSaIcE
eax, DWORD PTR [esp+20]
DWORD PTR [esp+4], ebx
eax, 12
DWORD PTR [esp], eax
_ZNSs4_Rep10_M_disposeERKSaIcE
esp, [ebp-12]
eax, eax
ebx
esi
edi
ebp

, 12
( 3 ) , , .
std::string
++ : STL10 - .
, :
#include <stdio.h>
#include <string>
std::string s="a string";
int main()
{
printf ("%s\n", s.c_str());
};

Listing 2.18: MSVC 2012


$SG39512 DB
$SG39519 DB
PROC
cmp
00000010H
mov
cmovae
push
push
call
add
xor
ret
_main
ENDP

a string, 00H
%s, 0aH, 00H

_main

DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A+20, 16 ;


eax, OFFSET ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A ; s
eax, DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A
eax
OFFSET $SG39519
_printf
esp, 8
eax, eax
0

??__Es@@YAXXZ PROC
; dynamic initializer for s, COMDAT
push
8
push
OFFSET $SG39512
mov
ecx, OFFSET ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A ; s
call
?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std
::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign
push
OFFSET ??__Fs@@YAXXZ
; dynamic atexit destructor for s
call
_atexit
pop
ecx
ret
0
??__Es@@YAXXZ ENDP
; dynamic initializer for s
??__Fs@@YAXXZ PROC
push
ecx
10

; dynamic atexit destructor for s, COMDAT

(C++) Standard Template Library

153

2.4. STL

2. ++

cmp
DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A+20, 16 ;
00000010H
jb
SHORT $LN23@dynamic
push
esi
mov
esi, DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A
lea
ecx, DWORD PTR $T2[esp+8]
call
??0?$_Wrap_alloc@V?$allocator@D@std@@@std@@QAE@XZ ; std::_Wrap_alloc<std::allocator<char>
>::_Wrap_alloc<std::allocator<char> >
push
OFFSET ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A ; s
lea
ecx, DWORD PTR $T2[esp+12]
call
??$destroy@PAD@?$_Wrap_alloc@V?$allocator@D@std@@@std@@QAEXPAPAD@Z ; std::_Wrap_alloc<std
::allocator<char> >::destroy<char *>
lea
ecx, DWORD PTR $T1[esp+8]
call
??0?$_Wrap_alloc@V?$allocator@D@std@@@std@@QAE@XZ ; std::_Wrap_alloc<std::allocator<char>
>::_Wrap_alloc<std::allocator<char> >
push
esi
call
??3@YAXPAX@Z
; operator delete
add
esp, 4
pop
esi
$LN23@dynamic:
mov
DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A+20, 15 ;
0000000fH
mov
DWORD PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A+16, 0
mov
BYTE PTR ?s@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A, 0
pop
ecx
ret
0
??__Fs@@YAXXZ ENDP
; dynamic atexit destructor for s

, CRT, main(), -,
. : atexit() -,
: -
.
GCC :
Listing 2.19: GCC 4.8.1
main:
push
mov
and
sub
mov
mov
call
xor
leave
ret

ebp
ebp, esp
esp, -16
esp, 16
eax, DWORD PTR s
DWORD PTR [esp], eax
puts
eax, eax

.LC0:
.string "a string"
_GLOBAL__sub_I_s:
sub
esp, 44
lea
eax, [esp+31]
mov
DWORD PTR [esp+8], eax
mov
DWORD PTR [esp+4], OFFSET FLAT:.LC0
mov
DWORD PTR [esp], OFFSET FLAT:s
call
_ZNSsC1EPKcRKSaIcE
mov
DWORD PTR [esp+8], OFFSET FLAT:__dso_handle
mov
DWORD PTR [esp+4], OFFSET FLAT:s
mov
DWORD PTR [esp], OFFSET FLAT:_ZNSsD1Ev
call
__cxa_atexit
add
esp, 44
ret
.LFE645:
.size
_GLOBAL__sub_I_s, .-_GLOBAL__sub_I_s
.section
.init_array,"aw"
.align 4
.long
_GLOBAL__sub_I_s
.globl s
.bss
.align 4
.type
s, @object
.size
s, 4
s:
.zero
4
.hidden __dso_handle

154

2.4. STL
2. ++
- : atexit() .

2.4.2

std::list

: ,
.
2 (8 32-
16 64-).
, .
C++ STL next previous ,
.
,
.
++ [13] , , MSVC GCC
, :
#include <stdio.h>
#include <list>
#include <iostream>
struct a
{
int x;
int y;
};
struct List_node
{
struct List_node* _Next;
struct List_node* _Prev;
int x;
int y;
};
void dump_List_node (struct List_node *n)
{
printf ("ptr=0x%p _Next=0x%p _Prev=0x%p x=%d y=%d\n",
n, n->_Next, n->_Prev, n->x, n->y);
};
void dump_List_vals (struct List_node* n)
{
struct List_node* current=n;
for (;;)
{
dump_List_node (current);
current=current->_Next;
if (current==n) // end
break;
};
};
void dump_List_val (unsigned int *a)
{
#ifdef _MSC_VER
// GCC implementation doesnt have "size" field
printf ("_Myhead=0x%p, _Mysize=%d\n", a[0], a[1]);
#endif
dump_List_vals ((struct List_node*)a[0]);
};
int main()
{
std::list<struct a> l;
printf ("* empty list:\n");
dump_List_val((unsigned int*)(void*)&l);

155

2.4. STL

2. ++

struct a t1;
t1.x=1;
t1.y=2;
l.push_front (t1);
t1.x=3;
t1.y=4;
l.push_front (t1);
t1.x=5;
t1.y=6;
l.push_back (t1);
printf ("* 3-elements list:\n");
dump_List_val((unsigned int*)(void*)&l);
std::list<struct a>::iterator tmp;
printf ("node at .begin:\n");
tmp=l.begin();
dump_List_node ((struct List_node *)*(void**)&tmp);
printf ("node at .end:\n");
tmp=l.end();
dump_List_node ((struct List_node *)*(void**)&tmp);
printf ("* lets count from the begin:\n");
std::list<struct a>::iterator it=l.begin();
printf ("1st element: %d %d\n", (*it).x, (*it).y);
it++;
printf ("2nd element: %d %d\n", (*it).x, (*it).y);
it++;
printf ("3rd element: %d %d\n", (*it).x, (*it).y);
it++;
printf ("element at .end(): %d %d\n", (*it).x, (*it).y);
printf ("* lets count from the end:\n");
std::list<struct a>::iterator it2=l.end();
printf ("element at .end(): %d %d\n", (*it2).x, (*it2).y);
it2--;
printf ("3rd element: %d %d\n", (*it2).x, (*it2).y);
it2--;
printf ("2nd element: %d %d\n", (*it2).x, (*it2).y);
it2--;
printf ("1st element: %d %d\n", (*it2).x, (*it2).y);
printf ("removing last element...\n");
l.pop_back();
dump_List_val((unsigned int*)(void*)&l);
};

GCC
GCC.
, .
* empty list:
ptr=0x0028fe90 _Next=0x0028fe90 _Prev=0x0028fe90 x=3 y=0

. ,
. next prev :

156

2.4. STL

2. ++
list.begin()

std::list

list.end()

Next
Prev
X=garbage
Y=garbage

, .begin .end .
3 :
* 3-elements list:
ptr=0x000349a0 _Next=0x00034988
ptr=0x00034988 _Next=0x00034b40
ptr=0x00034b40 _Next=0x0028fe90
ptr=0x0028fe90 _Next=0x000349a0

_Prev=0x0028fe90
_Prev=0x000349a0
_Prev=0x00034988
_Prev=0x00034b40

x=3
x=1
x=5
x=5

y=4
y=2
y=6
y=6

0x0028fe90, -
. (5 6). ,
, , - .
3 :

std::list
list.begin()

list.end()

Next

Next

Next

Next

Prev

Prev

Prev

Prev

X=1-

X=2-

X=3-

X=

Y=1-

Y=2-

Y=3-

Y=

.
.begin() .end() , ,
.
. ,
, , .
. list.begin() list.end()
.
node at .begin:
ptr=0x000349a0 _Next=0x00034988 _Prev=0x0028fe90 x=3 y=4
node at .end:
ptr=0x0028fe90 _Next=0x000349a0 _Prev=0x00034b40 x=5 y=6

, : , ..,
, ,
. .
157

2.4. STL
2. ++
operator- operator++ current_node->prev
current_node->next. (.rbegin, .rend) , .
operator* , , .., ().
: ( ) , .
: . , ,
, .
GCC ( 4.8.1) :
.size(): ,
. (), .., ,
.
Listing 2.20: GCC 4.8.1 -O3 -fno-inline-small-functions
main

proc near
push
ebp
mov
ebp, esp
push
esi
push
ebx
and
esp, 0FFFFFFF0h
sub
esp, 20h
lea
ebx, [esp+10h]
mov
dword ptr [esp], offset s ; "* empty list:"
mov
[esp+10h], ebx
mov
[esp+14h], ebx
call
puts
mov
[esp], ebx
call
_Z13dump_List_valPj ; dump_List_val(uint *)
lea
esi, [esp+18h]
mov
[esp+4], esi
mov
[esp], ebx
mov
dword ptr [esp+18h], 1 ; X for new element
mov
dword ptr [esp+1Ch], 2 ; Y for new element
call
_ZNSt4listI1aSaIS0_EE10push_frontERKS0_ ; std::list<a,std::allocator<a>>::
push_front(a const&)
mov
[esp+4], esi
mov
[esp], ebx
mov
dword ptr [esp+18h], 3 ; X for new element
mov
dword ptr [esp+1Ch], 4 ; Y for new element
call
_ZNSt4listI1aSaIS0_EE10push_frontERKS0_ ; std::list<a,std::allocator<a>>::
push_front(a const&)
mov
dword ptr [esp], 10h
mov
dword ptr [esp+18h], 5 ; X for new element
mov
dword ptr [esp+1Ch], 6 ; Y for new element
call
_Znwj
; operator new(uint)
cmp
eax, 0FFFFFFF8h
jz
short loc_80002A6
mov
ecx, [esp+1Ch]
mov
edx, [esp+18h]
mov
[eax+0Ch], ecx
mov
[eax+8], edx

loc_80002A6:

; CODE XREF: main+86


mov
[esp+4], ebx
mov
[esp], eax
call
_ZNSt8__detail15_List_node_base7_M_hookEPS0_ ; std::__detail::_List_node_base::
_M_hook(std::__detail::_List_node_base*)
mov
dword ptr [esp], offset a3ElementsList ; "* 3-elements list:"
call
puts
mov
[esp], ebx
call
_Z13dump_List_valPj ; dump_List_val(uint *)
mov
dword ptr [esp], offset aNodeAt_begin ; "node at .begin:"
call
puts
mov
eax, [esp+10h]
mov
[esp], eax
call
_Z14dump_List_nodeP9List_node ; dump_List_node(List_node *)
mov
dword ptr [esp], offset aNodeAt_end ; "node at .end:"
call
puts
mov
[esp], ebx
call
_Z14dump_List_nodeP9List_node ; dump_List_node(List_node *)

158

2.4. STL
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
call
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
mov
mov
mov
mov
mov
mov
call
mov
call
mov
mov
call
_M_unhook(void)
mov
call
mov

2. ++
dword ptr [esp], offset aLetSCountFromT ; "* lets count from the begin:"
puts
esi, [esp+10h]
eax, [esi+0Ch]
[esp+0Ch], eax
eax, [esi+8]
dword ptr [esp+4], offset a1stElementDD ; "1st element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
esi, [esi] ; operator++: get ->next pointer
eax, [esi+0Ch]
[esp+0Ch], eax
eax, [esi+8]
dword ptr [esp+4], offset a2ndElementDD ; "2nd element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
esi, [esi] ; operator++: get ->next pointer
eax, [esi+0Ch]
[esp+0Ch], eax
eax, [esi+8]
dword ptr [esp+4], offset a3rdElementDD ; "3rd element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
eax, [esi] ; operator++: get ->next pointer
edx, [eax+0Ch]
[esp+0Ch], edx
eax, [eax+8]
dword ptr [esp+4], offset aElementAt_endD ; "element at .end(): %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
dword ptr [esp], offset aLetSCountFro_0 ; "* lets count from the end:"
puts
eax, [esp+1Ch]
dword ptr [esp+4], offset aElementAt_endD ; "element at .end(): %d %d\n"
dword ptr [esp], 1
[esp+0Ch], eax
eax, [esp+18h]
[esp+8], eax
__printf_chk
esi, [esp+14h]
eax, [esi+0Ch]
[esp+0Ch], eax
eax, [esi+8]
dword ptr [esp+4], offset a3rdElementDD ; "3rd element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
esi, [esi+4] ; operator--: get ->prev pointer
eax, [esi+0Ch]
[esp+0Ch], eax
eax, [esi+8]
dword ptr [esp+4], offset a2ndElementDD ; "2nd element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
eax, [esi+4] ; operator--: get ->prev pointer
edx, [eax+0Ch]
[esp+0Ch], edx
eax, [eax+8]
dword ptr [esp+4], offset a1stElementDD ; "1st element: %d %d\n"
dword ptr [esp], 1
[esp+8], eax
__printf_chk
dword ptr [esp], offset aRemovingLastEl ; "removing last element..."
puts
esi, [esp+14h]
[esp], esi
_ZNSt8__detail15_List_node_base9_M_unhookEv ; std::__detail::_List_node_base::
[esp], esi
_ZdlPv
[esp], ebx

; void *
; operator delete(void *)

159

2.4. STL
call
mov
call
_M_clear(void)
lea
xor
pop
pop
pop
retn
main
endp

2. ++
_Z13dump_List_valPj ; dump_List_val(uint *)
[esp], ebx
_ZNSt10_List_baseI1aSaIS0_EE8_M_clearEv ; std::_List_base<a,std::allocator<a>>::
esp, [ebp-8]
eax, eax
ebx
esi
ebp

Listing 2.21:
* empty list:
ptr=0x0028fe90 _Next=0x0028fe90
* 3-elements list:
ptr=0x000349a0 _Next=0x00034988
ptr=0x00034988 _Next=0x00034b40
ptr=0x00034b40 _Next=0x0028fe90
ptr=0x0028fe90 _Next=0x000349a0
node at .begin:
ptr=0x000349a0 _Next=0x00034988
node at .end:
ptr=0x0028fe90 _Next=0x000349a0
* lets count from the begin:
1st element: 3 4
2nd element: 1 2
3rd element: 5 6
element at .end(): 5 6
* lets count from the end:
element at .end(): 5 6
3rd element: 5 6
2nd element: 1 2
1st element: 3 4
removing last element...
ptr=0x000349a0 _Next=0x00034988
ptr=0x00034988 _Next=0x0028fe90
ptr=0x0028fe90 _Next=0x000349a0

_Prev=0x0028fe90 x=3 y=0


_Prev=0x0028fe90
_Prev=0x000349a0
_Prev=0x00034988
_Prev=0x00034b40

x=3
x=1
x=5
x=5

y=4
y=2
y=6
y=6

_Prev=0x0028fe90 x=3 y=4


_Prev=0x00034b40 x=5 y=6

_Prev=0x0028fe90 x=3 y=4


_Prev=0x000349a0 x=1 y=2
_Prev=0x00034988 x=5 y=6

MSVC
MSVC (2012) , .
.size() ((1)): . ,
/.
MSVC :

std::list
list.end()

list.begin()

Next

Next

Next

Next

Prev

Prev

Prev

Prev

X=

X=1-

X=2-

X=3-

Y=

Y=1-

Y=2-

Y=3-

GCC , MSVC .
160

2.4. STL

2. ++
Listing 2.22: MSVC 2012 /Fa2.asm /Ox /GS- /Ob1

_l$ = -16
; size = 8
_t1$ = -8
; size = 8
_main
PROC
sub
esp, 16
; 00000010H
push
ebx
push
esi
push
edi
push
0
push
0
lea
ecx, DWORD PTR _l$[esp+36]
mov
DWORD PTR _l$[esp+40], 0
; allocate first "garbage" element
call
?_Buynode0@?$_List_alloc@$0A@U?$_List_base_types@Ua@@V?
$allocator@Ua@@@std@@@std@@@std@@QAEPAU?$_List_node@Ua@@PAX@2@PAU32@0@Z ; std::_List_alloc<0,std::
_List_base_types<a,std::allocator<a> > >::_Buynode0
mov
edi, DWORD PTR __imp__printf
mov
ebx, eax
push
OFFSET $SG40685 ; * empty list:
mov
DWORD PTR _l$[esp+32], ebx
call
edi ; printf
lea
eax, DWORD PTR _l$[esp+32]
push
eax
call
?dump_List_val@@YAXPAI@Z
; dump_List_val
mov
esi, DWORD PTR [ebx]
add
esp, 8
lea
eax, DWORD PTR _t1$[esp+28]
push
eax
push
DWORD PTR [esi+4]
lea
ecx, DWORD PTR _l$[esp+36]
push
esi
mov
DWORD PTR _t1$[esp+40], 1 ; data for a new node
mov
DWORD PTR _t1$[esp+44], 2 ; data for a new node
; allocate new node
call
??$_Buynode@ABUa@@@?$_List_buy@Ua@@V?$allocator@Ua@@@std@@@std@@QAEPAU?
$_List_node@Ua@@PAX@1@PAU21@0ABUa@@@Z ; std::_List_buy<a,std::allocator<a> >::_Buynode<a const &>
mov
DWORD PTR [esi+4], eax
mov
ecx, DWORD PTR [eax+4]
mov
DWORD PTR _t1$[esp+28], 3 ; data for a new node
mov
DWORD PTR [ecx], eax
mov
esi, DWORD PTR [ebx]
lea
eax, DWORD PTR _t1$[esp+28]
push
eax
push
DWORD PTR [esi+4]
lea
ecx, DWORD PTR _l$[esp+36]
push
esi
mov
DWORD PTR _t1$[esp+44], 4 ; data for a new node
; allocate new node
call
??$_Buynode@ABUa@@@?$_List_buy@Ua@@V?$allocator@Ua@@@std@@@std@@QAEPAU?
$_List_node@Ua@@PAX@1@PAU21@0ABUa@@@Z ; std::_List_buy<a,std::allocator<a> >::_Buynode<a const &>
mov
DWORD PTR [esi+4], eax
mov
ecx, DWORD PTR [eax+4]
mov
DWORD PTR _t1$[esp+28], 5 ; data for a new node
mov
DWORD PTR [ecx], eax
lea
eax, DWORD PTR _t1$[esp+28]
push
eax
push
DWORD PTR [ebx+4]
lea
ecx, DWORD PTR _l$[esp+36]
push
ebx
mov
DWORD PTR _t1$[esp+44], 6 ; data for a new node
; allocate new node
call
??$_Buynode@ABUa@@@?$_List_buy@Ua@@V?$allocator@Ua@@@std@@@std@@QAEPAU?
$_List_node@Ua@@PAX@1@PAU21@0ABUa@@@Z ; std::_List_buy<a,std::allocator<a> >::_Buynode<a const &>
mov
DWORD PTR [ebx+4], eax
mov
ecx, DWORD PTR [eax+4]
push
OFFSET $SG40689 ; * 3-elements list:
mov
DWORD PTR _l$[esp+36], 3
mov
DWORD PTR [ecx], eax
call
edi ; printf
lea
eax, DWORD PTR _l$[esp+32]
push
eax
call
?dump_List_val@@YAXPAI@Z
; dump_List_val
push
OFFSET $SG40831 ; node at .begin:
call
edi ; printf
push
DWORD PTR [ebx] ; get next field of node $l$ variable points to
call
?dump_List_node@@YAXPAUList_node@@@Z
; dump_List_node

161

2.4. STL
push
call
push
call
push
call
mov
push
push
push
call
mov
push
push
push
call
mov
push
push
push
call
mov
add
push
push
push
call
push
call
push
push
push
call
mov
push
push
push
call
mov
push
push
push
call
mov
push
push
push
call
add
push
call
mov
add

2. ++
OFFSET $SG40835 ; node at .end:
edi ; printf
ebx ; pointer to the node $l$ variable points to!
?dump_List_node@@YAXPAUList_node@@@Z
; dump_List_node
OFFSET $SG40839 ; * lets count from the begin:
edi ; printf
esi, DWORD PTR [ebx] ; operator++: get ->next pointer
DWORD PTR [esi+12]
DWORD PTR [esi+8]
OFFSET $SG40846 ; 1st element: %d %d
edi ; printf
esi, DWORD PTR [esi] ; operator++: get ->next pointer
DWORD PTR [esi+12]
DWORD PTR [esi+8]
OFFSET $SG40848 ; 2nd element: %d %d
edi ; printf
esi, DWORD PTR [esi] ; operator++: get ->next pointer
DWORD PTR [esi+12]
DWORD PTR [esi+8]
OFFSET $SG40850 ; 3rd element: %d %d
edi ; printf
eax, DWORD PTR [esi] ; operator++: get ->next pointer
esp, 64
; 00000040H
DWORD PTR [eax+12]
DWORD PTR [eax+8]
OFFSET $SG40852 ; element at .end(): %d %d
edi ; printf
OFFSET $SG40853 ; * lets count from the end:
edi ; printf
DWORD PTR [ebx+12] ; use x and y fields from the node $l$ variable points to
DWORD PTR [ebx+8]
OFFSET $SG40860 ; element at .end(): %d %d
edi ; printf
esi, DWORD PTR [ebx+4] ; operator--: get ->prev pointer
DWORD PTR [esi+12]
DWORD PTR [esi+8]
OFFSET $SG40862 ; 3rd element: %d %d
edi ; printf
esi, DWORD PTR [esi+4] ; operator--: get ->prev pointer
DWORD PTR [esi+12]
DWORD PTR [esi+8]
OFFSET $SG40864 ; 2nd element: %d %d
edi ; printf
eax, DWORD PTR [esi+4] ; operator--: get ->prev pointer
DWORD PTR [eax+12]
DWORD PTR [eax+8]
OFFSET $SG40866 ; 1st element: %d %d
edi ; printf
esp, 64
; 00000040H
OFFSET $SG40867 ; removing last element...
edi ; printf
edx, DWORD PTR [ebx+4]
esp, 4

; prev=next?
; it is the only element, "garbage one"?
; if yes, do not delete it!
cmp
edx, ebx
je
SHORT $LN349@main
mov
ecx, DWORD PTR [edx+4]
mov
eax, DWORD PTR [edx]
mov
DWORD PTR [ecx], eax
mov
ecx, DWORD PTR [edx]
mov
eax, DWORD PTR [edx+4]
push
edx
mov
DWORD PTR [ecx+4], eax
call
??3@YAXPAX@Z
add
esp, 4
mov
DWORD PTR _l$[esp+32], 2
$LN349@main:
lea
eax, DWORD PTR _l$[esp+28]
push
eax
call
?dump_List_val@@YAXPAI@Z
mov
eax, DWORD PTR [ebx]
add
esp, 4
mov
DWORD PTR [ebx], ebx

; operator delete

; dump_List_val

162

2.4. STL
mov
cmp
je
$LL414@main:
mov
push
call
add
mov
cmp
jne
$LN412@main:
push
call
add
xor
pop
pop
pop
add
ret
_main
ENDP

2. ++
DWORD PTR [ebx+4], ebx
eax, ebx
SHORT $LN412@main
esi, DWORD PTR [eax]
eax
??3@YAXPAX@Z
esp, 4
eax, esi
esi, ebx
SHORT $LL414@main

; operator delete

ebx
??3@YAXPAX@Z
esp, 4
eax, eax
edi
esi
ebx
esp, 16
0

; operator delete

; 00000010H

GCC, MSVC - -
Buynode, ( GCC
).
Listing 2.23:
* empty list:
_Myhead=0x003CC258, _Mysize=0
ptr=0x003CC258 _Next=0x003CC258 _Prev=0x003CC258
* 3-elements list:
_Myhead=0x003CC258, _Mysize=3
ptr=0x003CC258 _Next=0x003CC288 _Prev=0x003CC2A0
ptr=0x003CC288 _Next=0x003CC270 _Prev=0x003CC258
ptr=0x003CC270 _Next=0x003CC2A0 _Prev=0x003CC288
ptr=0x003CC2A0 _Next=0x003CC258 _Prev=0x003CC270
node at .begin:
ptr=0x003CC288 _Next=0x003CC270 _Prev=0x003CC258
node at .end:
ptr=0x003CC258 _Next=0x003CC288 _Prev=0x003CC2A0
* lets count from the begin:
1st element: 3 4
2nd element: 1 2
3rd element: 5 6
element at .end(): 6226002 4522072
* lets count from the end:
element at .end(): 6226002 4522072
3rd element: 5 6
2nd element: 1 2
1st element: 3 4
removing last element...
_Myhead=0x003CC258, _Mysize=2
ptr=0x003CC258 _Next=0x003CC288 _Prev=0x003CC270
ptr=0x003CC288 _Next=0x003CC270 _Prev=0x003CC258
ptr=0x003CC270 _Next=0x003CC258 _Prev=0x003CC288

x=6226002 y=4522072

x=6226002 y=4522072
x=3 y=4
x=1 y=2
x=5 y=6
x=3 y=4
x=6226002 y=4522072

x=6226002 y=4522072
x=3 y=4
x=1 y=2

C++11 std::forward_list
std::list, , .., next
. , .

2.4.3

std::vector

std::vector (wrapper) PODT11 .


std::string (2.4.1): ,
.
11

(C++) Plain Old Data Type

163

2.4. STL
2. ++
, (1.14).
C++11 .data() , .c_str()
std::string.
.
MSVC GCC , 12 ,
. - std::vector:
#include
#include
#include
#include

<stdio.h>
<vector>
<algorithm>
<functional>

struct vector_of_ints
{
// MSVC names:
int *Myfirst;
int *Mylast;
int *Myend;
// GCC structure is the same, names are: _M_start, _M_finish, _M_end_of_storage
};
void dump(struct vector_of_ints *in)
{
printf ("_Myfirst=0x%p, _Mylast=0x%p, _Myend=0x%p\n", in->Myfirst, in->Mylast, in->Myend);
size_t size=(in->Mylast-in->Myfirst);
size_t capacity=(in->Myend-in->Myfirst);
printf ("size=%d, capacity=%d\n", size, capacity);
for (size_t i=0; i<size; i++)
printf ("element %d: %d\n", i, in->Myfirst[i]);
};
int main()
{
std::vector<int> c;
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(1);
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(2);
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(3);
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(4);
dump ((struct vector_of_ints*)(void*)&c);
c.reserve (6);
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(5);
dump ((struct vector_of_ints*)(void*)&c);
c.push_back(6);
dump ((struct vector_of_ints*)(void*)&c);
printf ("%d\n", c.at(5)); // bounds checking
printf ("%d\n", c[8]); // operator[], no bounds checking
};

MSVC:
_Myfirst=0x00000000,
size=0, capacity=0
_Myfirst=0x0051CF48,
size=1, capacity=1
element 0: 1
_Myfirst=0x0051CF58,
size=2, capacity=2
element 0: 1
element 1: 2
_Myfirst=0x0051C278,
size=3, capacity=3
element 0: 1
element 1: 2
element 2: 3
_Myfirst=0x0051C290,
12

_Mylast=0x00000000, _Myend=0x00000000
_Mylast=0x0051CF4C, _Myend=0x0051CF4C

_Mylast=0x0051CF60, _Myend=0x0051CF60

_Mylast=0x0051C284, _Myend=0x0051C284

_Mylast=0x0051C2A0, _Myend=0x0051C2A0

GCC: http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a01371.html

164

2.4. STL

2. ++

size=4, capacity=4
element 0: 1
element 1: 2
element 2: 3
element 3: 4
_Myfirst=0x0051B180, _Mylast=0x0051B190, _Myend=0x0051B198
size=4, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
_Myfirst=0x0051B180, _Mylast=0x0051B194, _Myend=0x0051B198
size=5, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
element 4: 5
_Myfirst=0x0051B180, _Mylast=0x0051B198, _Myend=0x0051B198
size=6, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
element 4: 5
element 5: 6
6
6619158

, - main() .
push_back() . , push_back() (capacity) . , - push_back() . ,
.reserve(). : , . operator[] std::vector . .at() , ,
std::out_of_range .
:
Listing 2.24: MSVC 2012 /GS- /Ob1
$SG52650 DB
$SG52651 DB

%d, 0aH, 00H


%d, 0aH, 00H

_this$ = -4
; size = 4
__Pos$ = 8
; size = 4
?at@?$vector@HV?$allocator@H@std@@@std@@QAEAAHI@Z PROC ; std::vector<int,std::allocator<int> >::at,
COMDAT
; _this$ = ecx
push
ebp
mov
ebp, esp
push
ecx
mov
DWORD PTR _this$[ebp], ecx
mov
eax, DWORD PTR _this$[ebp]
mov
ecx, DWORD PTR _this$[ebp]
mov
edx, DWORD PTR [eax+4]
sub
edx, DWORD PTR [ecx]
sar
edx, 2
cmp
edx, DWORD PTR __Pos$[ebp]
ja
SHORT $LN1@at
push
OFFSET ??_C@_0BM@NMJKDPPO@invalid?5vector?$DMT?$DO?5subscript?$AA@
call
DWORD PTR __imp_?_Xout_of_range@std@@YAXPBD@Z
$LN1@at:
mov
eax, DWORD PTR _this$[ebp]
mov
ecx, DWORD PTR [eax]
mov
edx, DWORD PTR __Pos$[ebp]
lea
eax, DWORD PTR [ecx+edx*4]
$LN3@at:
mov
esp, ebp
pop
ebp
ret
4
?at@?$vector@HV?$allocator@H@std@@@std@@QAEAAHI@Z ENDP ; std::vector<int,std::allocator<int> >::at

165

2.4. STL

2. ++

_c$ =
$T1 =
$T2 =
$T3 =
$T4 =
$T5 =
$T6 =
_main

-36
; size = 12
-24
; size = 4
-20
; size = 4
-16
; size = 4
-12
; size = 4
-8
; size = 4
-4
; size = 4
PROC
push
ebp
mov
ebp, esp
sub
esp, 36
; 00000024H
mov
DWORD PTR _c$[ebp], 0
; Myfirst
mov
DWORD PTR _c$[ebp+4], 0
; Mylast
mov
DWORD PTR _c$[ebp+8], 0
; Myend
lea
eax, DWORD PTR _c$[ebp]
push
eax
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
mov
DWORD PTR $T6[ebp], 1
lea
ecx, DWORD PTR $T6[ebp]
push
ecx
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
edx, DWORD PTR _c$[ebp]
push
edx
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
mov
DWORD PTR $T5[ebp], 2
lea
eax, DWORD PTR $T5[ebp]
push
eax
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
ecx, DWORD PTR _c$[ebp]
push
ecx
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
mov
DWORD PTR $T4[ebp], 3
lea
edx, DWORD PTR $T4[ebp]
push
edx
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
eax, DWORD PTR _c$[ebp]
push
eax
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
mov
DWORD PTR $T3[ebp], 4
lea
ecx, DWORD PTR $T3[ebp]
push
ecx
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
edx, DWORD PTR _c$[ebp]
push
edx
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
push
6
lea
ecx, DWORD PTR _c$[ebp]
call
?reserve@?$vector@HV?$allocator@H@std@@@std@@QAEXI@Z ; std::vector<int,std::allocator<int>
>::reserve
lea
eax, DWORD PTR _c$[ebp]
push
eax
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
mov
DWORD PTR $T2[ebp], 5
lea
ecx, DWORD PTR $T2[ebp]
push
ecx
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
edx, DWORD PTR _c$[ebp]
push
edx
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump

166

2.4. STL

2. ++

add
esp, 4
mov
DWORD PTR $T1[ebp], 6
lea
eax, DWORD PTR $T1[ebp]
push
eax
lea
ecx, DWORD PTR _c$[ebp]
call
?push_back@?$vector@HV?$allocator@H@std@@@std@@QAEX$$QAH@Z ; std::vector<int,std::
allocator<int> >::push_back
lea
ecx, DWORD PTR _c$[ebp]
push
ecx
call
?dump@@YAXPAUvector_of_ints@@@Z
; dump
add
esp, 4
push
5
lea
ecx, DWORD PTR _c$[ebp]
call
?at@?$vector@HV?$allocator@H@std@@@std@@QAEAAHI@Z ; std::vector<int,std::allocator<int>
>::at
mov
edx, DWORD PTR [eax]
push
edx
push
OFFSET $SG52650 ; %d
call
DWORD PTR __imp__printf
add
esp, 8
mov
eax, 8
shl
eax, 2
mov
ecx, DWORD PTR _c$[ebp]
mov
edx, DWORD PTR [ecx+eax]
push
edx
push
OFFSET $SG52651 ; %d
call
DWORD PTR __imp__printf
add
esp, 8
lea
ecx, DWORD PTR _c$[ebp]
call
?_Tidy@?$vector@HV?$allocator@H@std@@@std@@IAEXXZ ; std::vector<int,std::allocator<int>
>::_Tidy
xor
eax, eax
mov
esp, ebp
pop
ebp
ret
0
_main
ENDP

.at() . ,
printf() , .
, size capacity,
std::string. . .
GCC , , .at() :
Listing 2.25: GCC 4.8.1 -fno-inline-small-functions -O1
main

proc near
push
ebp
mov
ebp, esp
push
edi
push
esi
push
ebx
and
esp, 0FFFFFFF0h
sub
esp, 20h
mov
dword ptr [esp+14h], 0
mov
dword ptr [esp+18h], 0
mov
dword ptr [esp+1Ch], 0
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 1
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]
mov
[esp], eax
call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 2
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]
mov
[esp], eax

167

2.4. STL

2. ++

call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 3
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]
mov
[esp], eax
call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 4
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]
mov
[esp], eax
call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
ebx, [esp+14h]
mov
eax, [esp+1Ch]
sub
eax, ebx
cmp
eax, 17h
ja
short loc_80001CF
mov
edi, [esp+18h]
sub
edi, ebx
sar
edi, 2
mov
dword ptr [esp], 18h
call
_Znwj
; operator new(uint)
mov
esi, eax
test
edi, edi
jz
short loc_80001AD
lea
eax, ds:0[edi*4]
mov
[esp+8], eax
; n
mov
[esp+4], ebx
; src
mov
[esp], esi
; dest
call
memmove
loc_80001AD:
mov
test
jz
mov
call

; CODE XREF: main+F8


eax, [esp+14h]
eax, eax
short loc_80001BD
[esp], eax
; void *
_ZdlPv
; operator delete(void *)

mov
lea
mov
add
mov

; CODE XREF: main+117


[esp+14h], esi
eax, [esi+edi*4]
[esp+18h], eax
esi, 18h
[esp+1Ch], esi

loc_80001BD:

loc_80001CF:

; CODE XREF: main+DD


lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 5
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]
mov
[esp], eax
call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
dword ptr [esp+10h], 6
lea
eax, [esp+10h]
mov
[esp+4], eax
lea
eax, [esp+14h]

168

2.4. STL

2. ++

mov
[esp], eax
call
_ZNSt6vectorIiSaIiEE9push_backERKi ; std::vector<int,std::allocator<int>>::
push_back(int const&)
lea
eax, [esp+14h]
mov
[esp], eax
call
_Z4dumpP14vector_of_ints ; dump(vector_of_ints *)
mov
eax, [esp+14h]
mov
edx, [esp+18h]
sub
edx, eax
cmp
edx, 17h
ja
short loc_8000246
mov
dword ptr [esp], offset aVector_m_range ; "vector::_M_range_check"
call
_ZSt20__throw_out_of_rangePKc ; std::__throw_out_of_range(char const*)
loc_8000246:

; CODE XREF: main+19C


mov
eax, [eax+14h]
mov
[esp+8], eax
mov
dword ptr [esp+4], offset aD ; "%d\n"
mov
dword ptr [esp], 1
call
__printf_chk
mov
eax, [esp+14h]
mov
eax, [eax+20h]
mov
[esp+8], eax
mov
dword ptr [esp+4], offset aD ; "%d\n"
mov
dword ptr [esp], 1
call
__printf_chk
mov
eax, [esp+14h]
test
eax, eax
jz
short loc_80002AC
mov
[esp], eax
; void *
call
_ZdlPv
; operator delete(void *)
jmp
short loc_80002AC
; --------------------------------------------------------------------------mov
ebx, eax
mov
edx, [esp+14h]
test
edx, edx
jz
short loc_80002A4
mov
[esp], edx
; void *
call
_ZdlPv
; operator delete(void *)
loc_80002A4:

; CODE XREF: main+1FE


mov
[esp], ebx
call
_Unwind_Resume
; --------------------------------------------------------------------------loc_80002AC:

; CODE XREF: main+1EA


; main+1F4
mov
lea
pop
pop
pop
pop

locret_80002B8:

main

eax, 0
esp, [ebp-0Ch]
ebx
esi
edi
ebp
; DATA XREF: .eh_frame:08000510
; .eh_frame:080005BC

retn
endp

.reserve() main(). new() , memmove() ,


delete() .
GCC:
_Myfirst=0x(nil), _Mylast=0x(nil), _Myend=0x(nil)
size=0, capacity=0
_Myfirst=0x0x8257008, _Mylast=0x0x825700c, _Myend=0x0x825700c
size=1, capacity=1
element 0: 1
_Myfirst=0x0x8257018, _Mylast=0x0x8257020, _Myend=0x0x8257020
size=2, capacity=2
element 0: 1
element 1: 2
_Myfirst=0x0x8257028, _Mylast=0x0x8257034, _Myend=0x0x8257038
size=3, capacity=4

169

2.4. STL
element 0: 1
element 1: 2
element 2: 3
_Myfirst=0x0x8257028,
size=4, capacity=4
element 0: 1
element 1: 2
element 2: 3
element 3: 4
_Myfirst=0x0x8257040,
size=4, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
_Myfirst=0x0x8257040,
size=5, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
element 4: 5
_Myfirst=0x0x8257040,
size=6, capacity=6
element 0: 1
element 1: 2
element 2: 3
element 3: 4
element 4: 5
element 5: 6
6
0

2. ++

_Mylast=0x0x8257038, _Myend=0x0x8257038

_Mylast=0x0x8257050, _Myend=0x0x8257058

_Mylast=0x0x8257054, _Myend=0x0x8257058

_Mylast=0x0x8257058, _Myend=0x0x8257058

MSVC.
, MSVC
~50% , , GCC 100% , ..,
.

2.4.4

std::map std::set

. , ,
2 . / .
, - (AKA ).
:
.
.
, - .
.
: : 0, 1, 2, 3, 5, 6, 9, 10, 11, 12,
20, 99, 100, 101, 107, 1001, 1010.

170

2.4. STL

2. ++
10

100

20

12

11

107

99

101

1001

1010

, .
, .
, : : , : , .
, , , , -
.
.
, log2 . 10 1000 , 13 10000 . ,
: .., .

.
, AVL- - . ,
.
std::map std::set GCC MSVC - .
std::set . std::map set: (value) .
MSVC
#include
#include
#include
#include

<map>
<set>
<string>
<iostream>

// struct is not packed!


struct tree_node
{
struct tree_node *Left;
struct tree_node *Parent;
struct tree_node *Right;
char Color; // 0 - Red, 1 - Black
char Isnil;
//std::pair Myval;
unsigned int first; // called Myval in std::set
const char *second; // not present in std::set
};
struct tree_struct
{
struct tree_node *Myhead;
size_t Mysize;
};

171

2.4. STL

2. ++

void dump_tree_node (struct tree_node *n, bool is_set, bool traverse)


{
printf ("ptr=0x%p Left=0x%p Parent=0x%p Right=0x%p Color=%d Isnil=%d\n",
n, n->Left, n->Parent, n->Right, n->Color, n->Isnil);
if (n->Isnil==0)
{
if (is_set)
printf ("first=%d\n", n->first);
else
printf ("first=%d second=[%s]\n", n->first, n->second);
}
if (traverse)
{
if (n->Isnil==1)
dump_tree_node (n->Parent, is_set, true);
else
{
if (n->Left->Isnil==0)
dump_tree_node (n->Left, is_set, true);
if (n->Right->Isnil==0)
dump_tree_node (n->Right, is_set, true);
};
};
};
const char* ALOT_OF_TABS="\t\t\t\t\t\t\t\t\t\t\t";
void dump_as_tree (int tabs, struct tree_node *n, bool is_set)
{
if (is_set)
printf ("%d\n", n->first);
else
printf ("%d [%s]\n", n->first, n->second);
if (n->Left->Isnil==0)
{
printf ("%.*sL-------", tabs, ALOT_OF_TABS);
dump_as_tree (tabs+1, n->Left, is_set);
};
if (n->Right->Isnil==0)
{
printf ("%.*sR-------", tabs, ALOT_OF_TABS);
dump_as_tree (tabs+1, n->Right, is_set);
};
};
void dump_map_and_set(struct tree_struct *m, bool is_set)
{
printf ("ptr=0x%p, Myhead=0x%p, Mysize=%d\n", m, m->Myhead, m->Mysize);
dump_tree_node (m->Myhead, is_set, true);
printf ("As a tree:\n");
printf ("root----");
dump_as_tree (1, m->Myhead->Parent, is_set);
};
int main()
{
// map
std::map<int, const char*> m;
m[10]="ten";
m[20]="twenty";
m[3]="three";
m[101]="one hundred one";
m[100]="one hundred";
m[12]="twelve";
m[107]="one hundred seven";
m[0]="zero";
m[1]="one";
m[6]="six";
m[99]="ninety-nine";
m[5]="five";
m[11]="eleven";
m[1001]="one thousand one";
m[1010]="one thousand ten";

172

2.4. STL

2. ++

m[2]="two";
m[9]="nine";
printf ("dumping m as map:\n");
dump_map_and_set ((struct tree_struct *)(void*)&m, false);
std::map<int, const char*>::iterator it1=m.begin();
printf ("m.begin():\n");
dump_tree_node ((struct tree_node *)*(void**)&it1, false, false);
it1=m.end();
printf ("m.end():\n");
dump_tree_node ((struct tree_node *)*(void**)&it1, false, false);
// set
std::set<int> s;
s.insert(123);
s.insert(456);
s.insert(11);
s.insert(12);
s.insert(100);
s.insert(1001);
printf ("dumping s as set:\n");
dump_map_and_set ((struct tree_struct *)(void*)&s, true);
std::set<int>::iterator it2=s.begin();
printf ("s.begin():\n");
dump_tree_node ((struct tree_node *)*(void**)&it2, true, false);
it2=s.end();
printf ("s.end():\n");
dump_tree_node ((struct tree_node *)*(void**)&it2, true, false);
};

Listing 2.26: MSVC 2012


dumping m as map:
ptr=0x0020FE04, Myhead=0x005BB3A0, Mysize=17
ptr=0x005BB3A0 Left=0x005BB4A0 Parent=0x005BB3C0
ptr=0x005BB3C0 Left=0x005BB4C0 Parent=0x005BB3A0
first=10 second=[ten]
ptr=0x005BB4C0 Left=0x005BB4A0 Parent=0x005BB3C0
first=1 second=[one]
ptr=0x005BB4A0 Left=0x005BB3A0 Parent=0x005BB4C0
first=0 second=[zero]
ptr=0x005BB520 Left=0x005BB400 Parent=0x005BB4C0
first=5 second=[five]
ptr=0x005BB400 Left=0x005BB5A0 Parent=0x005BB520
first=3 second=[three]
ptr=0x005BB5A0 Left=0x005BB3A0 Parent=0x005BB400
first=2 second=[two]
ptr=0x005BB4E0 Left=0x005BB3A0 Parent=0x005BB520
first=6 second=[six]
ptr=0x005BB5C0 Left=0x005BB3A0 Parent=0x005BB4E0
first=9 second=[nine]
ptr=0x005BB440 Left=0x005BB3E0 Parent=0x005BB3C0
first=100 second=[one hundred]
ptr=0x005BB3E0 Left=0x005BB460 Parent=0x005BB440
first=20 second=[twenty]
ptr=0x005BB460 Left=0x005BB540 Parent=0x005BB3E0
first=12 second=[twelve]
ptr=0x005BB540 Left=0x005BB3A0 Parent=0x005BB460
first=11 second=[eleven]
ptr=0x005BB500 Left=0x005BB3A0 Parent=0x005BB3E0
first=99 second=[ninety-nine]
ptr=0x005BB480 Left=0x005BB420 Parent=0x005BB440
first=107 second=[one hundred seven]
ptr=0x005BB420 Left=0x005BB3A0 Parent=0x005BB480
first=101 second=[one hundred one]
ptr=0x005BB560 Left=0x005BB3A0 Parent=0x005BB480
first=1001 second=[one thousand one]
ptr=0x005BB580 Left=0x005BB3A0 Parent=0x005BB560
first=1010 second=[one thousand ten]
As a tree:
root----10 [ten]
L-------1 [one]
L-------0 [zero]
R-------5 [five]
L-------3 [three]

Right=0x005BB580 Color=1 Isnil=1


Right=0x005BB440 Color=1 Isnil=0
Right=0x005BB520 Color=1 Isnil=0
Right=0x005BB3A0 Color=1 Isnil=0
Right=0x005BB4E0 Color=0 Isnil=0
Right=0x005BB3A0 Color=1 Isnil=0
Right=0x005BB3A0 Color=0 Isnil=0
Right=0x005BB5C0 Color=1 Isnil=0
Right=0x005BB3A0 Color=0 Isnil=0
Right=0x005BB480 Color=1 Isnil=0
Right=0x005BB500 Color=0 Isnil=0
Right=0x005BB3A0 Color=1 Isnil=0
Right=0x005BB3A0 Color=0 Isnil=0
Right=0x005BB3A0 Color=1 Isnil=0
Right=0x005BB560 Color=0 Isnil=0
Right=0x005BB3A0 Color=1 Isnil=0
Right=0x005BB580 Color=1 Isnil=0
Right=0x005BB3A0 Color=0 Isnil=0

173

2.4. STL

2. ++

L-------2 [two]
R-------6 [six]
R-------9 [nine]
R-------100 [one hundred]
L-------20 [twenty]
L-------12 [twelve]
L-------11 [eleven]
R-------99 [ninety-nine]
R-------107 [one hundred seven]
L-------101 [one hundred one]
R-------1001 [one thousand one]
R-------1010 [one thousand ten]
m.begin():
ptr=0x005BB4A0 Left=0x005BB3A0 Parent=0x005BB4C0 Right=0x005BB3A0 Color=1 Isnil=0
first=0 second=[zero]
m.end():
ptr=0x005BB3A0 Left=0x005BB4A0 Parent=0x005BB3C0 Right=0x005BB580 Color=1 Isnil=1
dumping s as set:
ptr=0x0020FDFC, Myhead=0x005BB5E0, Mysize=6
ptr=0x005BB5E0 Left=0x005BB640 Parent=0x005BB600
ptr=0x005BB600 Left=0x005BB660 Parent=0x005BB5E0
first=123
ptr=0x005BB660 Left=0x005BB640 Parent=0x005BB600
first=12
ptr=0x005BB640 Left=0x005BB5E0 Parent=0x005BB660
first=11
ptr=0x005BB680 Left=0x005BB5E0 Parent=0x005BB660
first=100
ptr=0x005BB620 Left=0x005BB5E0 Parent=0x005BB600
first=456
ptr=0x005BB6A0 Left=0x005BB5E0 Parent=0x005BB620
first=1001
As a tree:
root----123
L-------12
L-------11
R-------100
R-------456
R-------1001
s.begin():
ptr=0x005BB640 Left=0x005BB5E0 Parent=0x005BB660
first=11
s.end():
ptr=0x005BB5E0 Left=0x005BB640 Parent=0x005BB600

Right=0x005BB6A0 Color=1 Isnil=1


Right=0x005BB620 Color=1 Isnil=0
Right=0x005BB680 Color=1 Isnil=0
Right=0x005BB5E0 Color=0 Isnil=0
Right=0x005BB5E0 Color=0 Isnil=0
Right=0x005BB6A0 Color=1 Isnil=0
Right=0x005BB5E0 Color=0 Isnil=0

Right=0x005BB5E0 Color=0 Isnil=0

Right=0x005BB6A0 Color=1 Isnil=1

, char 4 .
std::map, first second std::pair. std::set
.
, std::list MSVC (2.4.2).
std::list, . .begin() . ( ),
. operator- operator++ -, .., .
[7].
.end() , 1 Isnil,
/ . landing zone HDD13 .
GCC
#include
#include
#include
#include
#include

<stdio.h>
<map>
<set>
<string>
<iostream>

struct map_pair
{
13

Hard disk drive

174

2.4. STL

2. ++

int key;
const char *value;
};
struct tree_node
{
int M_color; // 0 - Red, 1 - Black
struct tree_node *M_parent;
struct tree_node *M_left;
struct tree_node *M_right;
};
struct tree_struct
{
int M_key_compare;
struct tree_node M_header;
size_t M_node_count;
};
void dump_tree_node (struct tree_node *n, bool is_set, bool traverse, bool dump_keys_and_values)
{
printf ("ptr=0x%p M_left=0x%p M_parent=0x%p M_right=0x%p M_color=%d\n",
n, n->M_left, n->M_parent, n->M_right, n->M_color);
void *point_after_struct=((char*)n)+sizeof(struct tree_node);
if (dump_keys_and_values)
{
if (is_set)
printf ("key=%d\n", *(int*)point_after_struct);
else
{
struct map_pair *p=(struct map_pair *)point_after_struct;
printf ("key=%d value=[%s]\n", p->key, p->value);
};
};
if (traverse==false)
return;
if (n->M_left)
dump_tree_node (n->M_left, is_set, traverse, dump_keys_and_values);
if (n->M_right)
dump_tree_node (n->M_right, is_set, traverse, dump_keys_and_values);
};
const char* ALOT_OF_TABS="\t\t\t\t\t\t\t\t\t\t\t";
void dump_as_tree (int tabs, struct tree_node *n, bool is_set)
{
void *point_after_struct=((char*)n)+sizeof(struct tree_node);
if (is_set)
printf ("%d\n", *(int*)point_after_struct);
else
{
struct map_pair *p=(struct map_pair *)point_after_struct;
printf ("%d [%s]\n", p->key, p->value);
}
if (n->M_left)
{
printf ("%.*sL-------", tabs, ALOT_OF_TABS);
dump_as_tree (tabs+1, n->M_left, is_set);
};
if (n->M_right)
{
printf ("%.*sR-------", tabs, ALOT_OF_TABS);
dump_as_tree (tabs+1, n->M_right, is_set);
};
};
void dump_map_and_set(struct tree_struct *m, bool is_set)
{
printf ("ptr=0x%p, M_key_compare=0x%x, M_header=0x%p, M_node_count=%d\n",
m, m->M_key_compare, &m->M_header, m->M_node_count);

175

2.4. STL

2. ++

dump_tree_node (m->M_header.M_parent, is_set, true, true);


printf ("As a tree:\n");
printf ("root----");
dump_as_tree (1, m->M_header.M_parent, is_set);
};
int main()
{
// map
std::map<int, const char*> m;
m[10]="ten";
m[20]="twenty";
m[3]="three";
m[101]="one hundred one";
m[100]="one hundred";
m[12]="twelve";
m[107]="one hundred seven";
m[0]="zero";
m[1]="one";
m[6]="six";
m[99]="ninety-nine";
m[5]="five";
m[11]="eleven";
m[1001]="one thousand one";
m[1010]="one thousand ten";
m[2]="two";
m[9]="nine";
printf ("dumping m as map:\n");
dump_map_and_set ((struct tree_struct *)(void*)&m, false);
std::map<int, const char*>::iterator it1=m.begin();
printf ("m.begin():\n");
dump_tree_node ((struct tree_node *)*(void**)&it1, false, false, true);
it1=m.end();
printf ("m.end():\n");
dump_tree_node ((struct tree_node *)*(void**)&it1, false, false, false);
// set
std::set<int> s;
s.insert(123);
s.insert(456);
s.insert(11);
s.insert(12);
s.insert(100);
s.insert(1001);
printf ("dumping s as set:\n");
dump_map_and_set ((struct tree_struct *)(void*)&s, true);
std::set<int>::iterator it2=s.begin();
printf ("s.begin():\n");
dump_tree_node ((struct tree_node *)*(void**)&it2, true, false, true);
it2=s.end();
printf ("s.end():\n");
dump_tree_node ((struct tree_node *)*(void**)&it2, true, false, false);
};

Listing 2.27: GCC 4.8.1


dumping m as map:
ptr=0x0028FE3C, M_key_compare=0x402b70, M_header=0x0028FE40, M_node_count=17
ptr=0x007A4988 M_left=0x007A4C00 M_parent=0x0028FE40 M_right=0x007A4B80 M_color=1
key=10 value=[ten]
ptr=0x007A4C00 M_left=0x007A4BE0 M_parent=0x007A4988 M_right=0x007A4C60 M_color=1
key=1 value=[one]
ptr=0x007A4BE0 M_left=0x00000000 M_parent=0x007A4C00 M_right=0x00000000 M_color=1
key=0 value=[zero]
ptr=0x007A4C60 M_left=0x007A4B40 M_parent=0x007A4C00 M_right=0x007A4C20 M_color=0
key=5 value=[five]
ptr=0x007A4B40 M_left=0x007A4CE0 M_parent=0x007A4C60 M_right=0x00000000 M_color=1
key=3 value=[three]
ptr=0x007A4CE0 M_left=0x00000000 M_parent=0x007A4B40 M_right=0x00000000 M_color=0
key=2 value=[two]
ptr=0x007A4C20 M_left=0x00000000 M_parent=0x007A4C60 M_right=0x007A4D00 M_color=1

176

2.4. STL

2. ++

key=6 value=[six]
ptr=0x007A4D00 M_left=0x00000000 M_parent=0x007A4C20 M_right=0x00000000
key=9 value=[nine]
ptr=0x007A4B80 M_left=0x007A49A8 M_parent=0x007A4988 M_right=0x007A4BC0
key=100 value=[one hundred]
ptr=0x007A49A8 M_left=0x007A4BA0 M_parent=0x007A4B80 M_right=0x007A4C40
key=20 value=[twenty]
ptr=0x007A4BA0 M_left=0x007A4C80 M_parent=0x007A49A8 M_right=0x00000000
key=12 value=[twelve]
ptr=0x007A4C80 M_left=0x00000000 M_parent=0x007A4BA0 M_right=0x00000000
key=11 value=[eleven]
ptr=0x007A4C40 M_left=0x00000000 M_parent=0x007A49A8 M_right=0x00000000
key=99 value=[ninety-nine]
ptr=0x007A4BC0 M_left=0x007A4B60 M_parent=0x007A4B80 M_right=0x007A4CA0
key=107 value=[one hundred seven]
ptr=0x007A4B60 M_left=0x00000000 M_parent=0x007A4BC0 M_right=0x00000000
key=101 value=[one hundred one]
ptr=0x007A4CA0 M_left=0x00000000 M_parent=0x007A4BC0 M_right=0x007A4CC0
key=1001 value=[one thousand one]
ptr=0x007A4CC0 M_left=0x00000000 M_parent=0x007A4CA0 M_right=0x00000000
key=1010 value=[one thousand ten]
As a tree:
root----10 [ten]
L-------1 [one]
L-------0 [zero]
R-------5 [five]
L-------3 [three]
L-------2 [two]
R-------6 [six]
R-------9 [nine]
R-------100 [one hundred]
L-------20 [twenty]
L-------12 [twelve]
L-------11 [eleven]
R-------99 [ninety-nine]
R-------107 [one hundred seven]
L-------101 [one hundred one]
R-------1001 [one thousand one]
R-------1010 [one thousand ten]
m.begin():
ptr=0x007A4BE0 M_left=0x00000000 M_parent=0x007A4C00 M_right=0x00000000
key=0 value=[zero]
m.end():
ptr=0x0028FE40 M_left=0x007A4BE0 M_parent=0x007A4988 M_right=0x007A4CC0
dumping s as set:
ptr=0x0028FE20, M_key_compare=0x8, M_header=0x0028FE24, M_node_count=6
ptr=0x007A1E80 M_left=0x01D5D890 M_parent=0x0028FE24 M_right=0x01D5D850
key=123
ptr=0x01D5D890 M_left=0x01D5D870 M_parent=0x007A1E80 M_right=0x01D5D8B0
key=12
ptr=0x01D5D870 M_left=0x00000000 M_parent=0x01D5D890 M_right=0x00000000
key=11
ptr=0x01D5D8B0 M_left=0x00000000 M_parent=0x01D5D890 M_right=0x00000000
key=100
ptr=0x01D5D850 M_left=0x00000000 M_parent=0x007A1E80 M_right=0x01D5D8D0
key=456
ptr=0x01D5D8D0 M_left=0x00000000 M_parent=0x01D5D850 M_right=0x00000000
key=1001
As a tree:
root----123
L-------12
L-------11
R-------100
R-------456
R-------1001
s.begin():
ptr=0x01D5D870 M_left=0x00000000 M_parent=0x01D5D890 M_right=0x00000000
key=11
s.end():
ptr=0x0028FE24 M_left=0x01D5D870 M_parent=0x007A1E80 M_right=0x01D5D8D0

M_color=0
M_color=1
M_color=0
M_color=1
M_color=0
M_color=1
M_color=0
M_color=1
M_color=1
M_color=0

M_color=1

M_color=0

M_color=1
M_color=1
M_color=0
M_color=0
M_color=1
M_color=0

M_color=0

M_color=0

GCC 14 . Isnil,
MSVC.
14

http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.1/stl__tree_8h-source.html

177

2.4. STL
.end(), / .

178

2. ++

3. -

-
3.1

. -
:
push
mov
sub

ebp
ebp, esp
esp, X

: EBP , EBP
ESP, .
EBP ,
. ESP,
.
, EBP
:
mov
pop
ret

esp, ebp
ebp
0

.
, .
, - ,
.
, .

3.2

npad

, .
, , ,
. ,
, , .
listing.inc (MSVC):
, , NOP-.
, .
;;
;;
;;
;;
;;
;;
;;

LISTING.INC
This file contains assembler macros and is included by the files created
with the -FA compiler switch to be assembled by MASM (Microsoft Macro
Assembler).
Copyright (c) 1993-2003, Microsoft Corporation. All rights reserved.

;; non destructive nops


npad macro size

179

3.2. NPAD

3. -

if size eq 1
nop
else
if size eq 2
mov edi, edi
else
if size eq 3
; lea ecx, [ecx+00]
DB 8DH, 49H, 00H
else
if size eq 4
; lea esp, [esp+00]
DB 8DH, 64H, 24H, 00H
else
if size eq 5
add eax, DWORD PTR 0
else
if size eq 6
; lea ebx, [ebx+00000000]
DB 8DH, 9BH, 00H, 00H, 00H, 00H
else
if size eq 7
; lea esp, [esp+00000000]
DB 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H
else
if size eq 8
; jmp .+8; .npad 6
DB 0EBH, 06H, 8DH, 9BH, 00H, 00H, 00H, 00H
else
if size eq 9
; jmp .+9; .npad 7
DB 0EBH, 07H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H
else
if size eq 10
; jmp .+A; .npad 7; .npad 1
DB 0EBH, 08H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 90H
else
if size eq 11
; jmp .+B; .npad 7; .npad 2
DB 0EBH, 09H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8BH, 0FFH
else
if size eq 12
; jmp .+C; .npad 7; .npad 3
DB 0EBH, 0AH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 49H, 00H
else
if size eq 13
; jmp .+D; .npad 7; .npad 4
DB 0EBH, 0BH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 64H, 24H, 00H
else
if size eq 14
; jmp .+E; .npad 7; .npad 5
DB 0EBH, 0CH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 05H, 00H, 00H, 00H, 00H
else
if size eq 15
; jmp .+F; .npad 7; .npad 6
DB 0EBH, 0DH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 9BH, 00H, 00H, 00H, 00H
else
%out error: unsupported npad size
.err
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endm

180

3.3.

3.3

3. -

1 , x86 twos complement.


/ , , , ,
0xFFFFFFFE 0x0000002 , (4294967294)
(2). , 2, , ,
(2). (1.8)
( JG, JL) (JA, JBE).

3.3.1

integer

, /
integer.
, , .
. 32- . ,
, , , MAX_PACKET_SIZE (, 10 ), , . .
0xFFFFFFFF. 1 10000. . - . . .
memcpy (dst, src, 0xFFFFFFFF) , .
: [3].

3.4

3.4.1

cdecl

/++.
:
, , .
, .
Listing 3.1: cdecl
push arg3
push arg2
push arg3
call function
add esp, 12 ; returns ESP

3.4.2

stdcall

cdecl, ESP , RET x RET, x = _ *


sizeof(int)2 .
add esp, x.
Listing 3.2: stdcall
push
push
push
call

arg3
arg2
arg1
function

function:
... do something ...
ret 12
1
2

http://en.wikipedia.org/wiki/Signed_number_representations
int 4 x86- 8 x64-

181

3.4.
3. -
win32, win64 ( win64
).

printf(), , /++ , cdecl stdcall.
, printf(). ,
printf(), MSVCRT.DLL (
Windows), ,
. , printf() stdcall-
,
, . , stdcall , cdecl.

3.4.3

fastcall

.
, cdecl/stdcall ( ). , , CPU, .
, -. ,
, , DLL, , fastcall , .
MSVC GCC ECX EDX .
.
, stdcall.
Listing 3.3: fastcall
push arg3
mov edx, arg2
mov ecx, arg1
call function
function:
.. do something ..
ret 4

GCC regparm
, fastcall3 . -mregparm=x ,
. 3.
EAX, EDX ECX.
, , .
.
, . (1.15.1).

3.4.4

thiscall

++, - this .
MSVC this ECX.
GCC this . , : - .
, . (2.1.1).
3

http://www.ohse.de/uwe/articles/gcc-attributes.html#func-regparm

182

3.4.

3.4.5

3. -

x86-64

Windows x64
win64 fastcall. 4
RCX, RDX, R8, R9, .
32 64- ,

4 . ,

.
.
Windows x86-64 ( stdcall win32).
:
#include <stdio.h>
void f1(int a, int b, int c, int d, int e, int f, int g)
{
printf ("%d %d %d %d %d %d %d\n", a, b, c, d, e, f, g);
};
int main()
{
f1(1,2,3,4,5,6,7);
};

Listing 3.4: MSVC 2012 /0b


$SG2937 DB
main

main

%d %d %d %d %d %d %d, 0aH, 00H

PROC
sub

rsp, 72

mov
mov
mov
mov
mov
mov
mov
call

DWORD PTR [rsp+48], 7


DWORD PTR [rsp+40], 6
DWORD PTR [rsp+32], 5
r9d, 4
r8d, 3
edx, 2
ecx, 1
f1

xor
add
ret
ENDP

eax, eax
rsp, 72
0

a$ = 80
b$ = 88
c$ = 96
d$ = 104
e$ = 112
f$ = 120
g$ = 128
f1
PROC
$LN3:
mov
mov
mov
mov
sub
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
lea

DWORD PTR
DWORD PTR
DWORD PTR
DWORD PTR
rsp, 72

; 00000048H

; 00000048H

[rsp+32], r9d
[rsp+24], r8d
[rsp+16], edx
[rsp+8], ecx
; 00000048H

eax, DWORD PTR g$[rsp]


DWORD PTR [rsp+56], eax
eax, DWORD PTR f$[rsp]
DWORD PTR [rsp+48], eax
eax, DWORD PTR e$[rsp]
DWORD PTR [rsp+40], eax
eax, DWORD PTR d$[rsp]
DWORD PTR [rsp+32], eax
r9d, DWORD PTR c$[rsp]
r8d, DWORD PTR b$[rsp]
edx, DWORD PTR a$[rsp]
rcx, OFFSET FLAT:$SG2937

183

3.4.

f1

call

printf

add
ret
ENDP

rsp, 72
0

3. -

; 00000048H

7 : 4 3 .
- f1() scratch space
. , 4, -.
scratch space -.
Listing 3.5: MSVC 2012 /Ox /0b
$SG2777 DB

%d %d %d %d %d %d %d, 0aH, 00H

a$ = 80
b$ = 88
c$ = 96
d$ = 104
e$ = 112
f$ = 120
g$ = 128
f1
PROC
$LN3:
sub

rsp, 72

f1
main

main

; 00000048H

mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
lea
call

eax, DWORD PTR g$[rsp]


DWORD PTR [rsp+56], eax
eax, DWORD PTR f$[rsp]
DWORD PTR [rsp+48], eax
eax, DWORD PTR e$[rsp]
DWORD PTR [rsp+40], eax
DWORD PTR [rsp+32], r9d
r9d, r8d
r8d, edx
edx, ecx
rcx, OFFSET FLAT:$SG2777
printf

add
ret
ENDP

rsp, 72
0

; 00000048H

PROC
sub

rsp, 72

; 00000048H

mov
mov
mov
lea
lea
lea
mov
call

edx, 2
DWORD PTR [rsp+48], 7
DWORD PTR [rsp+40], 6
r9d, QWORD PTR [rdx+2]
r8d, QWORD PTR [rdx+1]
ecx, QWORD PTR [rdx-1]
DWORD PTR [rsp+32], 5
f1

xor
add
ret
ENDP

eax, eax
rsp, 72
0

; 00000048H

, , scratch space
, .
MSVC 2012 LEA (11.5.6). , .
Linux x64
Linux x86-64 Windows, 6 4 (RDI, RSI, RDX, RCX, R8, R9), scratch space, callee
, .
184

3.5. -

3. -
Listing 3.6: GCC 4.7.3 -O3

.LC0:
.string "%d %d %d %d %d %d %d\n"
f1:
sub
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
xor
call
add
ret

rsp, 40
eax, DWORD PTR [rsp+48]
DWORD PTR [rsp+8], r9d
r9d, ecx
DWORD PTR [rsp], r8d
ecx, esi
r8d, edx
esi, OFFSET FLAT:.LC0
edx, edi
edi, 1
DWORD PTR [rsp+16], eax
eax, eax
__printf_chk
rsp, 40

sub
mov
mov
mov
mov
mov
mov
mov
call
add
ret

rsp, 24
r9d, 6
r8d, 5
DWORD PTR [rsp], 7
ecx, 4
edx, 3
esi, 2
edi, 1
f1
rsp, 24

main:

N.B.: 32- ( EAX) 64-


(RAX). x86-64, 32- 64-
32 . ,
x86-64.

3.4.6

float, double

Win64, float double FPU


ST(0).
Win64 float double XMM0 ST(0).

3.5

(.so) Linux, :
Listing 3.7: libc-2.17.so x86
.text:0012D5E3 __x86_get_pc_thunk_bx proc near
.text:0012D5E3
.text:0012D5E3
mov
ebx, [esp+0]
.text:0012D5E6
retn
.text:0012D5E6 __x86_get_pc_thunk_bx endp

; CODE XREF: sub_17350+3


; sub_173CC+4 ...

...
.text:000576C0 sub_576C0

proc near

; CODE XREF: tmpfile+73

...
.text:000576C0
.text:000576C1
.text:000576C8
.text:000576C9
.text:000576CA
.text:000576CB
.text:000576D0
.text:000576D6

push
mov
push
push
push
call
add
sub

ebp
ecx, large gs:0
edi
esi
ebx
__x86_get_pc_thunk_bx
ebx, 157930h
esp, 9Ch

185

3.5. -

3. -

...
.text:000579F0
.text:000579F6
.text:000579FA
c"
.text:00057A00
.text:00057A04
__gen_tempname\""
.text:00057A0A
.text:00057A12
.text:00057A15

lea
mov
lea

eax, (a__gen_tempname - 1AF000h)[ebx] ; "__gen_tempname"


[esp+0ACh+var_A0], eax
eax, (a__SysdepsPosix - 1AF000h)[ebx] ; "../sysdeps/posix/tempname.

mov
lea

[esp+0ACh+var_A8], eax
eax, (aInvalidKindIn_ - 1AF000h)[ebx] ; "! \"invalid KIND in

mov
mov
call

[esp+0ACh+var_A4], 14Ah
[esp+0ACh+var_AC], eax
__assert_fail

EBX,
. - (PIC4 ), ,
.
PIC 5 ,
( ).
*NIX ,
, .
,
.
:
#include <stdio.h>
int global_variable=123;
int f1(int var)
{
int rt=global_variable+var;
printf ("returning %d\n", rt);
return rt;
};

GCC 4.7.3 .so IDA:


gcc -fPIC -shared -O3 -o 1.so 1.c

Listing 3.8: GCC 4.7.3


.text:00000440
public __x86_get_pc_thunk_bx
.text:00000440 __x86_get_pc_thunk_bx proc near
; CODE XREF: _init_proc+4
.text:00000440
; deregister_tm_clones+4 ...
.text:00000440
mov
ebx, [esp+0]
.text:00000443
retn
.text:00000443 __x86_get_pc_thunk_bx endp
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000570
.text:00000573
.text:00000577
.text:0000057C
.text:00000582
.text:00000586
.text:0000058C
.text:0000058E
.text:00000594
4
5

f1

public f1
proc near

var_1C
var_18
var_14
var_8
var_4
arg_0

=
=
=
=
=
=

dword
dword
dword
dword
dword
dword

sub
mov
call
add
mov
mov
mov
lea
add

ptr
ptr
ptr
ptr
ptr
ptr

-1Ch
-18h
-14h
-8
-4
4

esp, 1Ch
[esp+1Ch+var_8], ebx
__x86_get_pc_thunk_bx
ebx, 1A84h
[esp+1Ch+var_4], esi
eax, ds:(global_variable_ptr - 2000h)[ebx]
esi, [eax]
eax, (aReturningD - 2000h)[ebx] ; "returning %d\n"
esi, [esp+1Ch+arg_0]

Position Independent Code


embedded

186

3.5. -
.text:00000598
.text:0000059C
.text:000005A3
.text:000005A7
.text:000005AC
.text:000005AE
.text:000005B2
.text:000005B6
.text:000005B9
.text:000005B9 f1

mov
mov
mov
call
mov
mov
mov
add
retn
endp

3. -
[esp+1Ch+var_18], eax
[esp+1Ch+var_1C], 1
[esp+1Ch+var_14], esi
___printf_chk
eax, esi
ebx, [esp+1Ch+var_8]
esi, [esp+1Ch+var_4]
esp, 1Ch

: returning %d\n global_variable __x86_get_pc_thunk_bx()


(: 0x57C) EBX.
(EIP) . 0x1A84 Global Offset Table Procedure Linkage Table (GOT PLT), , Global Offset Table (GOT),
global_variable. IDA ,
, :
.text:00000577
.text:0000057C
.text:00000582
.text:00000586
.text:0000058C
.text:0000058E

call
add
mov
mov
mov
lea

__x86_get_pc_thunk_bx
ebx, 1A84h
[esp+1Ch+var_4], esi
eax, [ebx-0Ch]
esi, [eax]
eax, [ebx-1A30h]

, EBX GOT PLT global_variable, GOT, 0xC. returning %d\n, 0x1A30.


, AMD64 RIP6 ,
PIC-.
GCC, x64.
IDA RIP, objdump :
0000000000000720
720:
48 8b 05
727:
53
728:
89 fb
72a:
48 8d 35
731:
bf 01 00
736:
03 18
738:
31 c0
73a:
89 da
73c:
e8 df fe
741:
89 d8
743:
5b
744:
c3

<f1>:
b9 08 20 00

20 00 00 00
00 00

ff ff

mov
push
mov
lea
mov
add
xor
mov
call
mov
pop
ret

rax,QWORD PTR [rip+0x2008b9]


# 200fe0 <_DYNAMIC+0x1d0>
rbx
ebx,edi
rsi,[rip+0x20]
# 751 <_fini+0x9>
edi,0x1
ebx,DWORD PTR [rax]
eax,eax
edx,ebx
620 <__printf_chk@plt>
eax,ebx
rbx

0x2008b9 0x720 global_variable, 0x20


0x72A returning %d\n.
,
( x64). ,
(static linking) ( [9]).

3.5.1

Windows

Windows DLL. Windows DLL


, DLL ( FIXUP-) .
DLL ,

DLL .
6

AMD64

187

3.6. THREAD LOCAL STORAGE

3.6

3. -

Thread Local Storage

, . , .
, errno. errno,
, errno TLS.
C++11 thread_local
, , TLS 7 :
Listing 3.9: C++11
#include <iostream>
#include <thread>
thread_local int tmp=3;
int main()
{
std::cout << tmp << std::endl;
};
8

PE-, tmp
TLS.

3.7

LD_PRELOAD Linux

, ,
libc.so.6.
, - . , time(), read(), write(), .
, uptime , , . strace(6.0.2), ,
/proc/uptime :
$ strace uptime
...
open("/proc/uptime", O_RDONLY)
lseek(3, 0, SEEK_SET)
read(3, "416166.86 414629.38\n", 2047)
...

= 3
= 0
= 20

, ,
Linux. :
$ cat /proc/uptime
416690.91 415152.03

wikipedia, :

The first number is the total number of seconds the system has been up. The second number
is how much of that time the machine has spent idle, in seconds.

9
7

C11 ,
MinGW GCC 4.8.1, MSVC 2012
9
https://en.wikipedia.org/wiki/Uptime
8

188

3.7. LD_PRELOAD LINUX


3. -
, open(), read(), close()
.
-, open() , ,
. -, read(), , , , read() libc.so.6.
close(), , .
- libc.so.6, dlopen() dlsym().
, -.
, , , strcmp(),
, strcmp() ,
- 10 .
#include
#include
#include
#include
#include
#include
#include

<stdio.h>
<stdarg.h>
<stdlib.h>
<stdbool.h>
<unistd.h>
<dlfcn.h>
<string.h>

void *libc_handle = NULL;


int (*open_ptr)(const char *, int) = NULL;
int (*close_ptr)(int) = NULL;
ssize_t (*read_ptr)(int, void*, size_t) = NULL;
bool inited = false;
_Noreturn void die (const char * fmt, ...)
{
va_list va;
va_start (va, fmt);
vprintf (fmt, va);
exit(0);
};
static void find_original_functions ()
{
if (inited)
return;
libc_handle = dlopen ("libc.so.6", RTLD_LAZY);
if (libc_handle==NULL)
die ("cant open libc.so.6\n");
open_ptr = dlsym (libc_handle, "open");
if (open_ptr==NULL)
die ("cant find open()\n");
close_ptr = dlsym (libc_handle, "close");
if (close_ptr==NULL)
die ("cant find close()\n");
read_ptr = dlsym (libc_handle, "read");
if (read_ptr==NULL)
die ("cant find read()\n");
inited = true;
}
static int opened_fd=0;
int open(const char *pathname, int flags)
{
find_original_functions();
int fd=(*open_ptr)(pathname, flags);
if (strcmp(pathname, "/proc/uptime")==0)
opened_fd=fd; // thats our file! record its file descriptor
else
10

, strcmp() Yong Huang

189

3.8. ITANIUM

3. -

opened_fd=0;
return fd;
};
int close(int fd)
{
find_original_functions();
if (fd==opened_fd)
opened_fd=0; // the file is not opened anymore
return (*close_ptr)(fd);
};
ssize_t read(int fd, void *buf, size_t count)
{
find_original_functions();
if (opened_fd!=0 && fd==opened_fd)
{
// thats our file!
return snprintf (buf, count, "%d %d", 0x7fffffff, 0x7fffffff)+1;
};
// not our file, go to real read() function
return (*read_ptr)(fd, buf, count);
};

:
gcc -fpic -shared -Wall -o fool_uptime.so fool_uptime.c -ldl

uptime, :
LD_PRELOAD=pwd/fool_uptime.so uptime

:
01:23:02 up 24855 days,

3:14,

3 users,

load average: 0.00, 0.01, 0.05

LD_PRELOAD , .
:
time() Sun Solaris http://yurichev.com/mirrors/LD_PRELOAD/sun_hack.txt
strcmp() (Yong Huang) http://yurichev.com/mirrors/LD_PRELOAD/
Yong%20Huang%20LD_PRELOAD.txt
Kevin Pulo Fun with LD_PRELOAD. . http://yurichev.com/mirrors/
LD_PRELOAD/lca2009.pdf
- (zlibc). ftp:
//metalab.unc.edu/pub/Linux/libs/compression

3.8

Itanium

( ) Intel Itanium (IA6411 ). OOE12 , EPIC13 :


.

IA64-: Linux:
11

Intel Architecture 64 (Itanium)


Out-of-order execution
13
Explicitly parallel instruction computing
12

190

3.8. ITANIUM

3. -
Listing 3.10: Linux kernel 3.2.0.4

#define TEA_ROUNDS
#define TEA_DELTA

32
0x9e3779b9

static void tea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)


{
u32 y, z, n, sum = 0;
u32 k0, k1, k2, k3;
struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *in = (const __le32 *)src;
__le32 *out = (__le32 *)dst;
y = le32_to_cpu(in[0]);
z = le32_to_cpu(in[1]);
k0
k1
k2
k3

=
=
=
=

ctx->KEY[0];
ctx->KEY[1];
ctx->KEY[2];
ctx->KEY[3];

n = TEA_ROUNDS;
while (n-- > 0) {
sum += TEA_DELTA;
y += ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
}
out[0] = cpu_to_le32(y);
out[1] = cpu_to_le32(z);
}

:
Listing 3.11: Linux Kernel 3.2.0.4 Itanium 2 (McKinley)
0090|
0090|08
0096|80
009C|00
00A0|09
00A6|F0
00AC|44
00B0|08
00B6|00
00BC|00
00C0|05
00CC|92
00D0|08
00D6|50
00DC|F0
00E0|0A
00E6|20
00EC|00
00F0|
00F0|
00F0|09
00F6|D0
00FC|A3
0100|03
0106|B0
010C|D3
0110|0B
0116|F0
011C|00
0120|00
0126|80
012C|F1
0130|0B
0136|A0
013C|00
0140|0B
0146|60
014C|00
0150|11
0156|E0

tea_encrypt:
adds r16 = 96, r32
adds r8 = 88, r32
nop.i 0
00 21
adds r3 = 92, r32
28 00
ld4 r15 = [r34], 4
adds r32 = 100, r32;;
10 10
ld4 r19 = [r16]
42 40
mov r16 = r0
mov.i r2 = ar.lc
10 10 9E FF FF FF 7F 20
ld4 r14 = [r34]
movl r17 = 0xFFFFFFFF9E3779B9;;
01 00
nop.m 0
20 00
ld4 r21 = [r8]
mov.i ar.lc = 31
10 10
ld4 r20 = [r3];;
20 00
ld4 r18 = [r32]
nop.i 0

80
C0
00
18
20
06
98
01
08
70
F3
00
01
09
A0
01
00

80
82
04
70
88
01
00
00
CA
00
CE
00
20
2A
00
80
04

41
00
00
41
20
84
20
00
00
44
6B
00
20
00
06
20
00

00 21
42 00

80
71
70
F0
E1
F1
C8
78
00
00
51
98
B8
C0
00
48
B9
00
00
70

40
54
68
40
50
3C
6C
64
04
00
3C
4C
3C
48
04
28
24
04
00
58

22
26
52
1C
00
80
34
00
00
00
34
80
20
00
00
16
1E
00
00
00

00 20
40 80
00 20
40 40
0F 20
40 00
01 00
29 60
00 20
40 00
0F 20
40 00
01 00
40 A0

loc_F0:
add r16 = r16, r17
shladd r29 = r14, 4,
extr.u r28 = r14, 5,
add r30 = r16, r14
add r27 = r28, r20;;
xor r26 = r29, r30;;
xor r25 = r27, r26;;
add r15 = r15, r25
nop.i 0;;
nop.m 0
extr.u r24 = r15, 5,
shladd r11 = r15, 4,
add r23 = r15, r16;;
add r10 = r24, r18
nop.i 0;;
xor r9 = r10, r11;;
xor r22 = r23, r9
nop.i 0;;
nop.m 0
add r14 = r14, r22

191

r21
27;;

// ptr to ctx->KEY[2]
// ptr to ctx->KEY[0]
//
//
//
//
//
//
//
//

ptr to ctx->KEY[1]
load z
ptr to ctx->KEY[3]
r19=k2
r0 always contain zero
save lc register
load y
TEA_DELTA

//
//
//
//

r21=k0
TEA_ROUNDS is 32
r20=k1
r18=k3

// r16=sum, r17=TEA_DELTA
// r14=y, r21=k0

// r20=k1

// r15=z

27
r19

// r19=k2
// r18=k3

3.9. BASIC BLOCK-


015C|A0
0160|09
0166|00
016C|20
0170|11
0176|00
017C|08

FF
20
00
08
00
00
00

FF
3C
00
AA
38
00
84

48
42
02
00
42
02
00

90 15
00 00
90 11
00 80

3. -
br.cloop.sptk.few loc_F0;;
st4 [r33] = r15, 4
nop.m 0
mov.i ar.lc = r2;;
st4 [r33] = r14
nop.i 0
br.ret.sptk.many b0;;

// store z
// restore lc register
// store y

, IA64 (bundle) .
16 template- . IDA 6+6+4
.
3 , -
-.
, Intel HP
(AKA templates): .
12. , MII, : Memory (
), I ( ).
, 0x1d: MFB: Memory ( ), Float
( FPU), Branch ( ).
, NOP14 : nop.i (NOP
) nop.m ( ). , NOP- .
. . -,
, -,
. , Itanium 2 2 , ,
6 .
(.., data
hazard-). , .
, - ;; ( ) . , [180-19c] : . :
[1a0-1bc].
- 22c. 230 -.
( CISC). : 236 ( r10),
. ,
, , , CPU , -
NOP-. :
.
- ,
Itanium, .
IA64- Linux:
http://lxr.free-electrons.com/source/arch/ia64/lib/.
Itanium: [5].
Itanium speculative execution ( ,
, ) NaT (not a thing), NaN-:
http://blogs.msdn.com/b/oldnewthing/archive/2004/01/19/60162.aspx.

3.9
3.9.1

basic block-
Profile-guided optimization

basic block-
.
14

No OPeration

192

3.9. BASIC BLOCK-


3. -
, - (, )
(, , ).
(instrumentation) ,
. , , .
, - ,
-.
Oracle RDBMS, Intel C++:
Listing 3.12: orageneric11.dll (win32)
_skgfsync

public _skgfsync
proc near

; address 0x6030D86A
db
nop
push
mov
mov
test
jz
mov
test
jnz

66h

mov
mov
mov
lea
and
mov
cmp
jnz
mov
pop
retn
endp

eax, [ebp+8]
edx, [ebp+10h]
dword ptr [eax], 0
eax, [edx+0Fh]
eax, 0FFFFFFFCh
ecx, [eax]
ecx, 45726963h
error
esp, ebp
ebp

ebp
ebp, esp
edx, [ebp+0Ch]
edx, edx
short loc_6030D884
eax, [edx+30h]
eax, 400h
__VInfreq__skgfsync

; write to log

continue:

_skgfsync

; exit with error

...
; address 0x60B953F0
__VInfreq__skgfsync:
mov
eax, [edx]
test
eax, eax
jz
continue
mov
ecx, [ebp+10h]
push
ecx
mov
ecx, [ebp+8]
push
edx
push
ecx
push
offset ... ; "skgfsync(se=0x%x, ctx=0x%x, iov=0x%x)\n"
push
dword ptr [edx+4]
call
dword ptr [eax] ; write to log
add
esp, 14h
jmp
continue
; --------------------------------------------------------------------------error:
mov
mov
mov
mov
mov
mov
pop
retn
; END OF FUNCTION CHUNK

edx, [ebp+8]
dword ptr [edx], 69AAh ; 27050 "function called with invalid FIB/IOV structure"
eax, [eax]
[edx+4], eax
dword ptr [edx+8], 0FA4h ; 4004
esp, ebp
ebp
FOR _skgfsync

9 .
DLL-, 193

3.9. BASIC BLOCK-


3. -
-. - Intel C++ VInfreg.
- - (, -
) Oracle ( ). Basic block -,
-
basic block 27050.
ELF- Linux Intel C++
(text.unlikely) text.hot.
reverse engineer-, -
.

194

4.


, -, .
, , .
DLL, . ( ++ STL .)
, , ( Boost1 , libpng2 ), .
/++, , , .
reverse engineer- .
IDA , , .
.lst .asm grep, awk,
.
, , -
libpng. ,
, . , . .
, - XML-, ,
XML- , - (
) .
, /
SAP 6.0. , .PDB- ,
.
CsDecomprLZC(). ,
MaxDB ( - SAP)3 .
http://www.google.com/search?q=CsDecomprLZC
, , MaxDB ,
, .

4.1

, API .
DLL-,
DLL, , .
, MessageBox() ,
: , , ,
MessageBox().
1

http://www.boost.org/
http://www.libpng.org/pub/png/libpng.html
3
(7.3.1)
2

195

4.1.
4.
, - ,
rand() ( Mersenne twister), ,
: .
, rand() , , .
rand() ( ): http:
//blog.yurichev.com/node/44.

4.1.1

- Windows API

(advapi32.dll): RegEnumKeyEx4 5 , RegEnumValue6 5 , RegGetValue7 5 , RegOpenKeyEx8


5 , RegQueryValueEx9 5 .
.ini- (kernel32.dll): GetPrivateProfileString 10 5 .
(user32.dll): MessageBox 11 5 , MessageBoxEx 12 5 , SetDlgItemText 13 5 , GetDlgItemText
14 5 .
(5.1.1): (user32.dll): LoadMenu 15 5 .
TCP/IP- (ws2_32.dll): WSARecv 16 , WSASend 17 .
(kernel32.dll): CreateFile 18 5 , ReadFile 19 , ReadFileEx 20 , WriteFile 21 , WriteFileEx 22 .
Internet (wininet.dll): WinHttpOpen 23 .
(wintrust.dll): WinVerifyTrust 24 .
MSVC ( ) (msvcr*.dll): assert, itoa, ltoa,
open, printf, read, strcmp, atol, atoi, fopen, fread, fwrite, memcmp, rand, strlen, strstr, strchr.

4.1.2

tracer: -

tracer 6.0.1 INT3-, ,


- DLL.
--one-time-INT3-bp:somedll.dll!.*

, INT3- , xml:
--one-time-INT3-bp:somedll.dll!xml.*
4

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724862(v=vs.85).aspx
-A ASCII- -W Unicode-
6
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724865(v=vs.85).aspx
7
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724868(v=vs.85).aspx
8
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724897(v=vs.85).aspx
9
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911(v=vs.85).aspx
10
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724353(v=vs.85).aspx
11
http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx
12
http://msdn.microsoft.com/en-us/library/ms645507(v=vs.85).aspx
13
http://msdn.microsoft.com/en-us/library/ms645521(v=vs.85).aspx
14
http://msdn.microsoft.com/en-us/library/ms645489(v=vs.85).aspx
15
http://msdn.microsoft.com/en-us/library/ms647990(v=vs.85).aspx
16
http://msdn.microsoft.com/en-us/library/windows/desktop/ms741688(v=vs.85).aspx
17
http://msdn.microsoft.com/en-us/library/windows/desktop/ms742203(v=vs.85).aspx
18
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
19
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx
20
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365468(v=vs.85).aspx
21
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx
22
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365748(v=vs.85).aspx
23
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx
24
http://msdn.microsoft.com/library/windows/desktop/aa388208.aspx
5

196

4.2.
4.
, .
Tracer - , , .
.
, ,
DLL, DLL. .
, , cygwin- uptime:
tracer -l:uptime.exe --one-time-INT3-bp:cygwin1.dll!.*

- cygwin1.dll, ,
:
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time
One-time

4.2

INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3
INT3

breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:
breakpoint:

cygwin1.dll!__main (called from uptime.exe!OEP+0x6d (0x40106d))


cygwin1.dll!_geteuid32 (called from uptime.exe!OEP+0xba3 (0x401ba3))
cygwin1.dll!_getuid32 (called from uptime.exe!OEP+0xbaa (0x401baa))
cygwin1.dll!_getegid32 (called from uptime.exe!OEP+0xcb7 (0x401cb7))
cygwin1.dll!_getgid32 (called from uptime.exe!OEP+0xcbe (0x401cbe))
cygwin1.dll!sysconf (called from uptime.exe!OEP+0x735 (0x401735))
cygwin1.dll!setlocale (called from uptime.exe!OEP+0x7b2 (0x4017b2))
cygwin1.dll!_open64 (called from uptime.exe!OEP+0x994 (0x401994))
cygwin1.dll!_lseek64 (called from uptime.exe!OEP+0x7ea (0x4017ea))
cygwin1.dll!read (called from uptime.exe!OEP+0x809 (0x401809))
cygwin1.dll!sscanf (called from uptime.exe!OEP+0x839 (0x401839))
cygwin1.dll!uname (called from uptime.exe!OEP+0x139 (0x401139))
cygwin1.dll!time (called from uptime.exe!OEP+0x22e (0x40122e))
cygwin1.dll!localtime (called from uptime.exe!OEP+0x236 (0x401236))
cygwin1.dll!sprintf (called from uptime.exe!OEP+0x25a (0x40125a))
cygwin1.dll!setutent (called from uptime.exe!OEP+0x3b1 (0x4013b1))
cygwin1.dll!getutent (called from uptime.exe!OEP+0x3c5 (0x4013c5))
cygwin1.dll!endutent (called from uptime.exe!OEP+0x3e6 (0x4013e6))
cygwin1.dll!puts (called from uptime.exe!OEP+0x4c3 (0x4014c3))

, . , , , . , printf()- ,
- , , , , release.
, , , . , Oracle
RDBMS : ksdwrt().
. IDA
, . .
, . Oracle RDBMS
.
.
, , . ,
, , , ,
. , ,
, .

4.3

assert()

assert() : -,
, .
assert-, .
, . , -
- .
197

4.4.

4.
Listing 4.1: assert()

.text:107D4B29
.text:107D4B2D
.text:107D4B30
.text:107D4B32
.text:107D4B37
.text:107D4B3C
"...
.text:107D4B41

mov
cmp
jz
push
push
push

dx, [ecx+42h]
edx, 1
short loc_107D4B4A
1ECh
offset aWrite_c ; "write.c"
offset aTdTd_planarcon ; "td->td_planarconfig == PLANARCONFIG_CON

call

ds:_assert

mov
and
test
jz
push
push
push
call

edx, [ebp-4]
edx, 3
edx, edx
short loc_107D52E9
58h
offset aDumpmode_c ; "dumpmode.c"
offset aN30
; "(n & 3) == 0"
ds:_assert

mov
cmp
jle
push
push
push
call

cx, [eax+6]
ecx, 0Ch
short loc_107D677A
2D8h
offset aLzw_c
; "lzw.c"
offset aSpLzw_nbitsBit ; "sp->lzw_nbits <= BITS_MAX"
ds:_assert

...
.text:107D52CA
.text:107D52CD
.text:107D52D0
.text:107D52D2
.text:107D52D4
.text:107D52D6
.text:107D52DB
.text:107D52E0
...
.text:107D6759
.text:107D675D
.text:107D6760
.text:107D6762
.text:107D6767
.text:107D676C
.text:107D6771

, - . , sp->lzw_nbits <= BITS_MAX, ,


- LZW-.

4.4

, , ,
IDA .
MD525 :
var
var
var
var

int
int
int
int

h0
h1
h2
h3

:=
:=
:=
:=

0x67452301
0xEFCDAB89
0x98BADCFE
0x10325476


MD5.

4.4.1

Magic numbers

magic numbers26 .
, Win32 MS-DOS MZ27 .
MIDI- MThd. - MIDI-
, MIDI-
4 .
:
(buf )
25

http://ru.wikipedia.org/wiki/MD5
http://en.wikipedia.org/wiki/Magic_number_(programming)
27
http://en.wikipedia.org/wiki/DOS_MZ_executable
26

198

4.5.
cmp [buf], 0x6468544D ; "MThd"
jnz _error_not_a_MIDI_file

4.

. . . memcmp() ,
CMPSB (11.5.6).
, MIDI-,
, , ,
.
DHCP

. , DHCP magic cookie: 0x63538263. - DHCP - -


.
. - DHCP - - magic cookie,
.
, dhcpcore.dll Windows 7 x64 . , : , DhcpExtractOptionsForValidat
DhcpExtractFullOptions():
Listing 4.2: dhcpcore.dll (Windows 7 x64)
.rdata:000007FF6483CBE8 dword_7FF6483CBE8 dd 63538263h
DhcpExtractOptionsForValidation+79
.rdata:000007FF6483CBEC dword_7FF6483CBEC dd 63538263h

; DATA XREF:
; DATA XREF: DhcpExtractFullOptions+97

:
Listing 4.3: dhcpcore.dll (Windows 7 x64)
.text:000007FF6480875F
.text:000007FF64808761
.text:000007FF64808767

mov
cmp
jnz

eax, [rsi]
eax, cs:dword_7FF6483CBE8
loc_7FF64817179

:
Listing 4.4: dhcpcore.dll (Windows 7 x64)
.text:000007FF648082C7
.text:000007FF648082CB
.text:000007FF648082D1

4.4.2

mov
cmp
jnz

eax, [r12]
eax, cs:dword_7FF6483CBEC
loc_7FF648173AF

IDA , Alt-B Alt-I. ,


, binary grep28 .

4.5

, ,
- .
, , Microsoft Excel
. , .
excel.exe ( Office 2010) 14.0.4756.1000 IDA,
FDIV ( ,
, , ):
cat EXCEL.lst | grep fdiv | grep -v dbl_ > EXCEL.fdiv
28

https://github.com/yurichev/bgrep

199

4.5.
4.
. . . , 144.
Excel =(1/3) .
tracer 6.0.1 ( 4 ),
, - 14- :
.text:3011E919 DC 33

fdiv

qword ptr [ebx]

PID=13944|TID=28744|(0) 0x2f64e919 (Excel.exe!BASE+0x11e919)


EAX=0x02088006 EBX=0x02088018 ECX=0x00000001 EDX=0x00000001
ESI=0x02088000 EDI=0x00544804 EBP=0x0274FA3C ESP=0x0274F9F8
EIP=0x2F64E919
FLAGS=PF IF
FPU ControlWord=IC RC=NEAR PC=64bits PM UM OM ZM DM IM
FPU StatusWord=
FPU ST(0): 1.000000

ST(0) (1), [ebx].


FDIV :
.text:3011E91B DD 1E

fstp

qword ptr [esi]

breakpoint , :
PID=32852|TID=36488|(0) 0x2f40e91b (Excel.exe!BASE+0x11e91b)
EAX=0x00598006 EBX=0x00598018 ECX=0x00000001 EDX=0x00000001
ESI=0x00598000 EDI=0x00294804 EBP=0x026CF93C ESP=0x026CF8F8
EIP=0x2F40E91B
FLAGS=PF IF
FPU ControlWord=IC RC=NEAR PC=64bits PM UM OM ZM DM IM
FPU StatusWord=C1 P
FPU ST(0): 0.333333

, 29 , :
tracer -l:excel.exe bpx=excel.exe!BASE+0x11E91B,set(st0,666)
PID=36540|TID=24056|(0) 0x2f40e91b (Excel.exe!BASE+0x11e91b)
EAX=0x00680006 EBX=0x00680018 ECX=0x00000001 EDX=0x00000001
ESI=0x00680000 EDI=0x00395404 EBP=0x0290FD9C ESP=0x0290FD58
EIP=0x2F40E91B
FLAGS=PF IF
FPU ControlWord=IC RC=NEAR PC=64bits PM UM OM ZM DM IM
FPU StatusWord=C1 P
FPU ST(0): 0.333333
Set ST0 register to 666.000000

Excel 666, .

. 4.1:
Excel, x64, FDIV 12,
.
29

practical joke

200

4.6.

4.

tracer.exe -l:excel.exe bpx=excel.exe!BASE+0x1B7FCC,set(st0,666)

, float double SSE- DIVSD, (DIVSD


268 ).

4.6
4.6.1

LOOP RCL. , . ,
- , . , /
.
, , .
Windows 2003 ( ntoskrnl.exe):
MultiplyTest

proc near
xor
cx, cx

loc_620555:
push
call
pop
jb
loop
clc
locret_620563:
MultiplyTest
Multiply

locret_62057F:

Multiply

; CODE XREF: Get386Stepping

; CODE XREF: MultiplyTest+E


cx
Multiply
cx
short locret_620563
loc_620555
; CODE XREF: MultiplyTest+C

retn
endp
proc near
; CODE XREF: MultiplyTest+5
mov
ecx, 81h
mov
eax, 417A000h
mul
ecx
cmp
edx, 2
stc
jnz
short locret_62057F
cmp
eax, 0FE7A000h
stc
jnz
short locret_62057F
clc
; CODE XREF: Multiply+10
; Multiply+18
retn
endp

, Windows Research Kernel v1.2,


WRK-v1.2\base\ntos\ke\i386\cpu.asm.

4.7

magic numbers

,
. , .
( 100%) magic
number.
- :
, . , , , , , ,
, .

201

4.8.
4.
32- 0x0badf00d, - 0x11101979
, 4 , -
.
, , , tracer 6.0.1 code coverage,
grep ,
, , .
tracer 6.0.1 cc, grep:
0x150bf66
0x150bf69
0x150bf6f
0x150bf75
0x150bf78

(_kziaia+0x14),
(_kziaia+0x17),
(_kziaia+0x1d),
(_kziaia+0x23),
(_kziaia+0x26),

e=
e=
e=
e=
e=

1
1
1
1
1

[MOV
[MOV
[FS:
[MOV
[MOV

EBX, [EBP+8]] [EBP+8]=0xf59c934


EDX, [69AEB08h]] [69AEB08h]=0
MOV EAX, [2Ch]]
ECX, [EAX+EDX*4]] [EAX+EDX*4]=0xf1ac360
[EBP-4], ECX] ECX=0xf1ac360

. magic number
.
tracer 6.0.1 , MS-DOS DosBox, heavydebug,
30 ,
DOS.

4.8

RTTI (2.1.5)- ++-.

4.9
4.9.1

, ,


8- .
, 8- (
, ), , , 100 ,
-. , 99 ,
, : - ,
100, 99.
, ,
.
, , NOP NOP-, 100 , . 8- ,
, - , ( BASIC POKE) ,
. POKE, 8- . .: http://en.wikipedia.org/wiki/PEEK_and_POKE.
( ),
, 8- . ,
- . , , , DOS- FC31 ( , , ). -
, , . , .

30
31

. DosBox: http://blog.yurichev.com/node/55
MS-DOS

202

5.


5.1
5.1.1


Win32 PE

PE , Windows.
.exe, .dll, .sys , .exe .sys , .
DLL1 , PE-, (OEP2 ) ( - DllMain()),
- .
.sys .
, Windows PE-
3.
Windows Vista, PE-- , .
PE- DOS-,
This program cannot be run in DOS mode. DOS Windows 3.1, .

, .exe .dll.
.
.exe- .dll-.
. .
, , , .
VA4 , .
, .
RVA5 VA- . PE-
RVA-.
IAT6 7 .
1

Dynamic-link library
Original Entry Point
3
, Hiew(6)
4
Virtual Address
5
Relative Virtual Address
6
Import Address Table
7
[19]
2

203

5.1.

5.

DLL- , , .
, DLL ,
, ,
DLL .
MSVC .exe- 0x400000, 0x401000. RVA 0x1000. DLL
0x10000000 8 .
, ,
, .
ASLR9 10 .
, , ,
- -.
( Windows NT: Windows Vista), DLL ( kernel32.dll, user32.dll)
, , DLL
, -, , .
, ASLR , ,
, .
PE-, ASLR
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE [23].
Subsystem
subsystem, native (.sys-), console ( ) GUI11
( ).

PE- Windows, . Windows, .
, MSVC 2005 .exe- Windows NT4 ( 4.00),
MSVC 2008 ( 5.00,
Windows 2000).
MSVC 2012 .exe- 6.00, Windows
Vista, , Windows XP.

, , .
, , .
IMAGE_SCN_CNT_CODE IMAGE_SCN_MEM_EXECUTE .

IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ IMAGE_SCN_MEM_WRITE.


8

/BASE
Address Space Layout Randomization
10
https://ru.wikipedia.org/wiki/Address_Space_Layout_Randomization
11
Graphical user interface
9

204

5.1.
5.
IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM
IMAGE_SCN_MEM_WRITE.
, , ,
IMAGE_SCN_CNT_INITIALIZED_DATA IMAGE_SCN_MEM_READ IMAGE_SCN_MEM_WRITE. - , .
PE- , . ( )
.text, .data, .rdata (readable data). : .idata ( ), .edata ( ), .reloc ( ),
.bss ( ), .tls thread local storage (TLS), .rsrc ().
/ PE- , .
MSVC 12 .

(, MinGW). MSVC (
PDB-).

FIXUP-.
13 .
, , , ? . (3.5). .
. .
, 0x410000 , :
A1 00 00 41 00

mov

eax,[000410000]

0x400000, RVA 0x10000.


0x500000,
0x510000.
, MOV, 0xA1.
, 0xA1, .
, 32- , ,
( RVA), .
, .
.
, Windows x86-,
IMAGE_REL_BASED_HIGHLOW.

, - DLL.
, ( DLL)
(.exe- DLL).
, DLL , - .
.exe-, DLL, , (IAT) -
DLL-.
12
13

http://msdn.microsoft.com/en-us/library/windows/desktop/cc307397.aspx
.exe- MS-DOS

205

5.1.
5.
, .exe-, IAT: DLL, - DLL IAT .exe-.
, , - , , , hint-,
- .
DLL. .
, MFC14 , mfc*.dll ,
, IAT, - MFC.
IDA, mfc*.dll,
-. IDA DLL, - - mfc80_123.
IAT (
.idata), .
- .
.
14

Microsoft Foundation Classes

206

5.1.

5.

. 5.1: , PE-,
, IMAGE_IMPORT_DESCRIPTOR. DLL.
RVA- ( DLL) (Name).
OriginalFirstThink RVA- RVA-, -. 16- (hint) -.
- , . . FirstThunk, RVA-
, -.
, IDA : __imp_CreateFileA, .
.
call __imp_CreateFileA, ,
- , ( 1 2)
call, .
207

5.1.
5.
, . -
. , , .
- - JMP . - thunk-. - CALL
thunk. , , CALL- , .
. , thunk, , .
, -, FirstThunk, IAT.
, PE_add_import15 .exe-.
-, DLL, :
MOV EAX, [yourdll.dll!function]
JMP EAX

, FirstThunk . , ,
yourdll.dll, - function .
, ,
IMAGE_SCN_MEM_WRITE . , 5
(access denied).
: DLL,
, - ?
, - FirstThunk .
IMAGE_IMPORT_DESCRIPTOR Timestamp. - , - DLL-. ,
, . old-style binding 16 . Windows SDK
BIND.EXE. , Matt Pietrek [19],
binding .
/ PE- / IAT. ,
Windows, , DLL. / ,
LoadLibrary() GetProcAddress().
DLL Windows, , IAT PE-.
. .exe- ( ), (map),
. Microsoft .

PE- , , , . ,
, , , .
, ,
, , ResHack(5.1.1).
15

http://yurichev.com/PE_add_import.html
http://blogs.msdn.com/b/oldnewthing/archive/2010/03/18/9980802.aspx. new-style
binding,
16

208

5.2. (SYSCALL-)
.NET

5.

.NET , . , .exe , , (OEP) x86:


jmp

mscoree.dll!_CorExeMain

mscoree.dll .NET-, PE-.


Windows XP. XP, .NET-
JMP 17 .
TLS
TLS(3.6) ( ).
, TLS- .
, PE- TLS-, .., TLS
callbacks. ,
(OEP). / PE-.

objdump ( cygwin) PE-.


Hiew(6) .
pefile Python- PE- 18 .
ResHack AKA Resource Hacker 19 .
Further reading
Daniel Pistelli The .NET File Format 20

5.2

(syscall-)

, :
(kernel space) (user space).
, , .
.
: - . ,
kernel panic BSOD21 .
x86- 4 (rings), Linux,
Windows, 2: ring0 (kernel space) ring3 (user space).
(syscall-) . , , API .
syscall- ,
- , syscall- , - API. ,
syscall-, , Windows, .
17

http://msdn.microsoft.com/en-us/library/xh0859k0(v=vs.110).aspx
https://code.google.com/p/pefile/
19
http://www.angusj.com/resourcehacker/
20
http://www.codeproject.com/Articles/12585/The-NET-File-Format
21
Black Screen of Death
18

209

5.3. WINDOWS NT:

5.2.1

5.

Linux

Linux syscall- int 0x80. EAX ,


- .
Listing 5.1: syscall-
section .text
global _start
_start:
mov
mov
mov
mov
int

edx,len
ecx,msg
ebx,1
eax,4
0x80

;
;
;
;

buf len
buf
file descriptor. stdout is 1
syscall number. sys_write is 4

mov
int

eax,1
0x80

; syscall number. sys_exit is 4

section .data
msg
len

db Hello, world!,0xa
equ $ - msg

:
nasm -f elf32 1.s
ld 1.o

syscall- Linux: http://syscalls.kernelgrok.com/.


Linux, strace(6.0.2).

5.2.2

Windows

int 0x2e x86- SYSENTER.


syscall- Windows: http://j00ru.vexillium.org/ntapi/.
:
Windows Syscall Shellcode by Piotr Bania.

5.3

Windows NT:

, , .
CRITICAL_SECTION OS Windows NT:
Listing 5.2: (Windows Research Kernel v1.2) public/sdk/inc/nturtl.h
typedef struct _RTL_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
//
//
//
//

The following three fields control entering and exiting the critical
section for the resource

LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
// from the threads ClientId->UniqueThread
HANDLE LockSemaphore;
ULONG_PTR SpinCount;
// force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

- EnterCriticalSection():

210

5.3. WINDOWS NT:


5.
Listing 5.3: Windows 2008/ntdll.dll/x86 (begin)
_RtlEnterCriticalSection@4
var_C
var_8
var_4
arg_0

=
=
=
=

dword
dword
dword
dword

ptr -0Ch
ptr -8
ptr -4
ptr 8

mov
edi, edi
push
ebp
mov
ebp, esp
sub
esp, 0Ch
push
esi
push
edi
mov
edi, [ebp+arg_0]
lea
esi, [edi+4] ; LockCount
mov
eax, esi
lock btr dword ptr [eax], 0
jnb
wait ; jump if CF=0
loc_7DE922DD:
mov
mov
mov
mov
pop
xor
pop
mov
pop
retn

eax, large fs:18h


ecx, [eax+24h]
[edi+0Ch], ecx
dword ptr [edi+8], 1
edi
eax, eax
esi
esp, ebp
ebp
4

... skipped

BTR ( LOCK):
CF . , ( LOCK BTR.
LockCount 1, , -: .
, .
WaitForSingleObject().
- LeaveCriticalSection():
Listing 5.4: Windows 2008/ntdll.dll/x86 (begin)
_RtlLeaveCriticalSection@4 proc near
arg_0

= dword ptr

mov
edi, edi
push
ebp
mov
ebp, esp
push
esi
mov
esi, [ebp+arg_0]
add
dword ptr [esi+8], 0FFFFFFFFh ; RecursionCount
jnz
short loc_7DE922B2
push
ebx
push
edi
lea
edi, [esi+4]
; LockCount
mov
dword ptr [esi+0Ch], 0
mov
ebx, 1
mov
eax, edi
lock xadd [eax], ebx
inc
ebx
cmp
ebx, 0FFFFFFFFh
jnz
loc_7DEA8EB7
loc_7DE922B0:
pop
pop

edi
ebx

xor

eax, eax

loc_7DE922B2:

211

5.3. WINDOWS NT:


pop
pop
retn

5.

esi
ebp
4

... skipped

XADD . , 1 LockCount,
EBX, 1 LockCount.
, LOCK, CPU CPU
.
LOCK : , CPU CPU,
,
, .

212

6.

IDA . : http://www.hex-rays.
com/idapro/idadownfreeware.htm.
Microsoft Visual Studio Express1 : Visual Studio,
.
Hiew2 .
binary grep: ( ) - , : https://github.com/yurichev/bgrep.

6.0.1

tracer 3 .
, :
- -
. , tracer. , , , , ,
, .
, , (, SoftICE, OllyDbg, WinDbg
), , , , , .

6.0.2

strace / dtruss
, (syscalls(5.2)) . :
# strace df -h
...
access("/etc/ld.so.nohwcap", F_OK)
= -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220\232\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1770984, ...}) = 0
mmap2(NULL, 1780508, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75b3000

MacOSX dtruss.
Cygwin strace, , , .exe cygwin.
1

http://www.microsoft.com/express/Downloads/
http://www.hiew.ru/
3
http://yurichev.com/tracer-ru.html
2

213

7.


7.1

, 1 .
: [28].

7.1.1

#1: MacOS Classic PowerPC

- MacOS Classic 2 , PowerPC.


, () .
, "Invalid Security
Device". .
Mac OS Classic, PowerPC, .
IDA , "PEF (Mac OS or Be OS executable)"(,
Mac OS Classic).
, :
...
seg000:000C87FC
seg000:000C8800
seg000:000C8804
seg000:000C8808
seg000:000C880C
seg000:000C8810

38
48
60
54
40
80

60
03
00
60
82
62

00
93
00
06
00
9F

01
41
00
3F
40
D8

li
bl
nop
clrlwi.
bne
lwz

%r3, 1
check1
%r0, %r3, 24
OK
%r3, TC_aInvalidSecurityDevice

...

, PowerPC. RISC 1990-. 4


( MIPS ARM) MIPS.
check1() - . BL Branch Link ..,
. BNE , :
r3
.
[25] r3 ( r4 64-).
CLRLWI. [10]
. , 24 r3
r0, MOVZX x86 (1.11.1), , BNE
.
check1():
seg000:00101B40
seg000:00101B40
1
2

check1:

# CODE XREF: seg000:00063E7Cp


# sub_64070+160p ...

: http://yurichev.com/dongles.html
MacOS UNIX

214

7.1.
seg000:00101B40
seg000:00101B40
seg000:00101B40
seg000:00101B40
seg000:00101B44
seg000:00101B48
seg000:00101B4C
seg000:00101B50
seg000:00101B54
seg000:00101B58
seg000:00101B5C
seg000:00101B60
seg000:00101B60

7.
.set arg_8,
7C
90
94
48
60
80
38
7C
4E

08
01
21
01
00
01
21
08
80

02
00
FF
6B
00
00
00
03
00

A6
08
C0
39
00
48
40
A6
20

mflr
%r0
stw
%r0, arg_8(%sp)
stwu
%sp, -0x40(%sp)
bl
check2
nop
lwz
%r0, 0x40+arg_8(%sp)
addi
%sp, %sp, 0x40
mtlr
%r0
blr
# End of function check1

IDA, - ,
r3 . -
-, thunk function: - , r3 ,
checkl() , check2().
BLR3 -, IDA - ,
. RISC, ,
link register, ARM.
- check2() :
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118684
seg000:00118688
seg000:0011868C
seg000:00118690
seg000:00118690
seg000:00118694
seg000:00118698
seg000:0011869C
seg000:001186A0
seg000:001186A4
seg000:001186A8
seg000:001186AC
seg000:001186B0
seg000:001186B4
seg000:001186B8
seg000:001186B8
seg000:001186B8
seg000:001186B8
seg000:001186BC
seg000:001186C0
seg000:001186C4
seg000:001186C4
seg000:001186C4
seg000:001186C8
seg000:001186CC
seg000:001186D0
seg000:001186D4
seg000:001186D8
seg000:001186DC
seg000:001186E0
seg000:001186E0
seg000:001186E0
seg000:001186E0
seg000:001186E4
seg000:001186E8
seg000:001186EC
seg000:001186F0
seg000:001186F4
seg000:001186F8
seg000:001186F8
3

check2:
.set
.set
.set
.set
.set
93 E1 FF FC
7C 08 02 A6
83 E2 95 A8
93
93
7C
90
54
28
94
40
38
48

C1
A1
7D
01
60
00
21
82
60
00

FF
FF
1B
00
06
00
FF
00
00
00

F8
F4
78
08
3E
01
B0
0C
01
6C

# CODE XREF: check1+Cp

var_18, -0x18
var_C, -0xC
var_8, -8
var_4, -4
arg_8, 8

stw
%r31, var_4(%sp)
mflr
%r0
lwz
%r31, off_1485E8 # dword_24B704
.using dword_24B704, %r31
stw
%r30, var_8(%sp)
stw
%r29, var_C(%sp)
mr
%r29, %r3
stw
%r0, arg_8(%sp)
clrlwi %r0, %r3, 24
cmplwi %r0, 1
stwu
%sp, -0x50(%sp)
bne
loc_1186B8
li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_1186B8:

48 00 03 D5
60 00 00 00
3B C0 00 00

# CODE XREF: check2+28j


bl
nop
li

sub_118A8C
%r30, 0

skip:
57
41
38
80
48
60
48

C0
82
61
9F
00
00
00

06
00
00
00
C0
00
00

3F
18
38
00
55
00
1C

80
38
38
48
60
3B

BF
81
60
00
00
C0

00
00
08
BF
00
00

00
38
C2
99
00
01

# CODE XREF: check2+94j


clrlwi. %r0, %r30, 24
beq
loc_1186E0
addi
%r3, %sp, 0x50+var_18
lwz
%r4, dword_24B704
bl
.RBEFINDNEXT
nop
b
loc_1186F8
# --------------------------------------------------------------------------loc_1186E0:
lwz
addi
li
bl
nop
li

# CODE XREF: check2+44j


%r5, dword_24B704
%r4, %sp, 0x50+var_18
%r3, 0x1234
.RBEFINDFIRST
%r30, 1

loc_1186F8:

# CODE XREF: check2+58j

(PowerPC) Branch to Link Register

215

7.1.
seg000:001186F8
seg000:001186FC
seg000:00118700
seg000:00118704
seg000:00118708
seg000:00118708
seg000:00118708
seg000:00118708
seg000:0011870C
seg000:00118710
seg000:00118714
seg000:00118718
seg000:0011871C
seg000:00118720
seg000:00118720
seg000:00118720
seg000:00118720
seg000:00118724
seg000:00118728
seg000:0011872C
seg000:00118730
seg000:00118734
seg000:00118738
seg000:00118738

7.
54
41
38
48

60
82
60
00

04
00
00
00

3F
0C
00
1C

7F
48
60
54
41
38

A3
00
00
60
82
60

EB
00
00
06
FF
00

78
31
00
3F
AC
01

clrlwi. %r0, %r3, 16


beq
must_jump
li
%r3, 0
# error
b
exit
# --------------------------------------------------------------------------must_jump:

# CODE XREF: check2+78j


mr
bl
nop
clrlwi.
beq
li

%r3, %r29
check3
%r0, %r3, 24
skip
%r3, 1

exit:
80
38
83
7C
83
83
4E

01
21
E1
08
C1
A1
80

00
00
FF
03
FF
FF
00

58
50
FC
A6
F8
F4
20

# CODE XREF: check2+30j


# check2+80j
%r0, 0x50+arg_8(%sp)
%sp, %sp, 0x50
%r31, var_4(%sp)
%r0
%r30, var_8(%sp)
%r29, var_C(%sp)

lwz
addi
lwz
mtlr
lwz
lwz
blr
# End of function check2

: - (
? , .. , - PE-
(5.1.1))? .RBEFINDNEXT() and .RBEFINDFIRST(). , - .GetNextDeviceViaUSB(), .USBSendPKT(), USB-.
- .GetNextEve3Device() , 1990-
Sentinel Eve3 ADB- ( ).
r3 .
r3 , r3
.
- li %r3, 1 li %r3, 0 (Load Immediate, .., ). 0x001186B0 ,
, PowerPC.
: .RBEFINDFIRST() , 0
r3 exit, - check3()
, .RBEFINDNEXT() , USB-.
N.B.: clrlwi. %r0, %r3, 16 , 16 ,
.., .RBEFINDFIRST() 16- .
B branch .
BEQ BNE.
check3():
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:0011873C
seg000:00118740
seg000:00118744
seg000:00118748
seg000:0011874C
seg000:00118750
seg000:00118750
seg000:00118754
seg000:00118758
seg000:0011875C
seg000:00118760
seg000:00118764
seg000:00118768

check3:
.set
.set
.set
.set
.set
93
7C
38
93
83

E1
08
A0
C1
C2

FF
02
00
FF
95

FC
A6
00
F8
A8

93
3B
38
90
94
80
38

A1
A3
60
01
21
DE
81

FF
00
00
00
FF
00
00

F4
00
00
08
B0
00
38

# CODE XREF: check2+88p

var_18, -0x18
var_C, -0xC
var_8, -8
var_4, -4
arg_8, 8
stw
%r31, var_4(%sp)
mflr
%r0
li
%r5, 0
stw
%r30, var_8(%sp)
lwz
%r30, off_1485E8 # dword_24B704
.using dword_24B704, %r30
stw
%r29, var_C(%sp)
addi
%r29, %r3, 0
li
%r3, 0
stw
%r0, arg_8(%sp)
stwu
%sp, -0x50(%sp)
lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18

216

7.1.
seg000:0011876C
seg000:00118770
seg000:00118774
seg000:00118778
seg000:0011877C
seg000:00118780
seg000:00118784
seg000:00118784
seg000:00118784
seg000:00118784
seg000:00118788
seg000:0011878C
seg000:00118790
seg000:00118794
seg000:00118798
seg000:00118798
seg000:00118798
seg000:00118798
seg000:0011879C
seg000:001187A0
seg000:001187A4
seg000:001187A8
seg000:001187AC
seg000:001187B0
seg000:001187B4
seg000:001187B8
seg000:001187BC
seg000:001187C0
seg000:001187C0
seg000:001187C0
seg000:001187C0
seg000:001187C4
seg000:001187C8
seg000:001187CC
seg000:001187D0
seg000:001187D4
seg000:001187D4
seg000:001187D4
seg000:001187D4
seg000:001187D8
seg000:001187DC
seg000:001187E0
seg000:001187E4
seg000:001187E8
seg000:001187EC
seg000:001187F0
seg000:001187F4
seg000:001187F8
seg000:001187F8
seg000:001187F8
seg000:001187F8
seg000:001187FC
seg000:00118800
seg000:00118804
seg000:00118804
seg000:00118804
seg000:00118804
seg000:00118808
seg000:0011880C
seg000:00118810
seg000:00118814
seg000:00118818
seg000:0011881C
seg000:00118820
seg000:00118824
seg000:00118828
seg000:0011882C
seg000:0011882C
seg000:0011882C
seg000:0011882C
seg000:00118830
seg000:00118834
seg000:00118838
seg000:0011883C
seg000:00118840
seg000:00118840

7.
48
60
54
41
38
48

00
00
60
82
60
00

C0
00
04
00
00
02

5D
00
3F
0C
00
F0

A0
28
41
38
48

01
00
82
60
00

00
04
00
00
02

38
B2
0C
00
DC

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
C0
00
04
00
00
02

00
38
01
00
21
00
3F
0C
00
B4

A0
28
41
38
48

01
00
82
60
00

00
06
00
00
02

38
4B
0C
00
A0

4B
60
54
2C
41
40
2C
40
48

F9
00
60
00
82
80
00
80
00

F3
00
06
00
01
00
00
00
01

D9
00
3E
05
00
10
04
58
8C

bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_118784
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118784:

# CODE XREF: check3+3Cj


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0x1100
beq
loc_118798
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118798:

# CODE XREF: check3+50j


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 1
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_1187C0
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1187C0:

# CODE XREF: check3+78j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0x09AB
beq
loc_1187D4
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1187D4:

# CODE XREF: check3+8Cj


bl
sub_B7BAC
nop
clrlwi %r0, %r3, 24
cmpwi
%r0, 5
beq
loc_1188E4
bge
loc_1187F8
cmpwi
%r0, 4
bge
loc_118848
b
loc_118980
# --------------------------------------------------------------------------loc_1187F8:

2C 00 00 0B
41 82 00 08
48 00 01 80

# CODE XREF: check3+ACj


cmpwi
%r0, 0xB
beq
loc_118804
b
loc_118980
# --------------------------------------------------------------------------loc_118804:

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BF
00
04
00
00
02

00
38
08
00
B5
00
3F
0C
00
48

A0
28
41
38
48

01
00
82
60
00

00
11
00
00
02

38
30
0C
00
34

# CODE XREF: check3+C0j


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 8
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_11882C
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_11882C:

# CODE XREF: check3+E4j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0xFEA0
beq
loc_118840
li
%r3, 0
b
exit
# ---------------------------------------------------------------------------

217

7.1.
seg000:00118840
seg000:00118840
seg000:00118844
seg000:00118848
seg000:00118848
seg000:00118848
seg000:00118848
seg000:0011884C
seg000:00118850
seg000:00118854
seg000:00118858
seg000:0011885C
seg000:00118860
seg000:00118864
seg000:00118868
seg000:0011886C
seg000:00118870
seg000:00118870
seg000:00118870
seg000:00118870
seg000:00118874
seg000:00118878
seg000:0011887C
seg000:00118880
seg000:00118884
seg000:00118884
seg000:00118884
seg000:00118884
seg000:00118888
seg000:0011888C
seg000:00118890
seg000:00118894
seg000:00118898
seg000:00118898
seg000:00118898
seg000:00118898
seg000:0011889C
seg000:001188A0
seg000:001188A4
seg000:001188A8
seg000:001188AC
seg000:001188B0
seg000:001188B4
seg000:001188B8
seg000:001188BC
seg000:001188C0
seg000:001188C0
seg000:001188C0
seg000:001188C0
seg000:001188C4
seg000:001188C8
seg000:001188CC
seg000:001188D0
seg000:001188D4
seg000:001188D4
seg000:001188D4
seg000:001188D4
seg000:001188D8
seg000:001188DC
seg000:001188E0
seg000:001188E4
seg000:001188E4
seg000:001188E4
seg000:001188E4
seg000:001188E8
seg000:001188EC
seg000:001188F0
seg000:001188F4
seg000:001188F8
seg000:001188FC
seg000:00118900
seg000:00118904
seg000:00118908
seg000:0011890C
seg000:0011890C
seg000:0011890C

7.
loc_118840:
38 60 00 01
48 00 02 2C

# CODE XREF: check3+F8j


li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_118848:

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BF
00
04
00
00
02

00
38
0A
00
71
00
3F
0C
00
04

A0
28
41
38
48

01
00
82
60
00

00
03
00
00
01

38
F3
0C
00
F0

57
28
40
38
48

BF
1F
82
60
00

06
00
00
00
01

3E
02
0C
01
DC

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BF
00
04
00
00
01

00
38
0B
00
21
00
3F
0C
00
B4

A0
28
41
38
48

01
00
82
60
00

00
23
00
00
01

38
1C
0C
00
A0

28
40
38
48

1F
82
60
00

00
01
00
01

03
94
01
90

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BE
00
04
00
00
01

00
38
0C
00
D5
00
3F
0C
00
68

# CODE XREF: check3+B4j


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 0xA
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_118870
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118870:

# CODE XREF: check3+128j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0xA6E1
beq
loc_118884
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118884:

# CODE XREF: check3+13Cj


clrlwi %r31, %r29, 24
cmplwi %r31, 2
bne
loc_118898
li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_118898:

# CODE XREF: check3+150j


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 0xB
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_1188C0
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1188C0:

# CODE XREF: check3+178j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0x1C20
beq
loc_1188D4
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1188D4:

# CODE XREF: check3+18Cj


cmplwi %r31, 3
bne
error
li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_1188E4:

# CODE XREF: check3+A8j


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 0xC
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_11890C
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_11890C:

# CODE XREF: check3+1C4j

218

7.1.
seg000:0011890C
seg000:00118910
seg000:00118914
seg000:00118918
seg000:0011891C
seg000:00118920
seg000:00118920
seg000:00118920
seg000:00118920
seg000:00118924
seg000:00118928
seg000:0011892C
seg000:00118930
seg000:00118934
seg000:00118934
seg000:00118934
seg000:00118934
seg000:00118938
seg000:0011893C
seg000:00118940
seg000:00118944
seg000:00118948
seg000:0011894C
seg000:00118950
seg000:00118954
seg000:00118958
seg000:0011895C
seg000:0011895C
seg000:0011895C
seg000:0011895C
seg000:00118960
seg000:00118964
seg000:00118968
seg000:0011896C
seg000:00118970
seg000:00118970
seg000:00118970
seg000:00118970
seg000:00118974
seg000:00118978
seg000:0011897C
seg000:00118980
seg000:00118980
seg000:00118980
seg000:00118980
seg000:00118980
seg000:00118984
seg000:00118988
seg000:0011898C
seg000:00118990
seg000:00118994
seg000:00118998
seg000:0011899C
seg000:001189A0
seg000:001189A4
seg000:001189A8
seg000:001189AC
seg000:001189AC
seg000:001189AC
seg000:001189AC
seg000:001189B0
seg000:001189B4
seg000:001189B8
seg000:001189BC
seg000:001189C0
seg000:001189C0
seg000:001189C0
seg000:001189C0
seg000:001189C4
seg000:001189C8
seg000:001189CC
seg000:001189D0
seg000:001189D0
seg000:001189D0
seg000:001189D0
seg000:001189D0

7.
A0
28
41
38
48

01
00
82
60
00

00
1F
00
00
01

38
40
0C
00
54

57
28
40
38
48

BF
1F
82
60
00

06
00
00
00
01

3E
02
0C
01
40

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BE
00
04
00
00
01

00
38
0D
00
85
00
3F
0C
00
18

A0
28
41
38
48

01
00
82
60
00

00
07
00
00
01

38
CF
0C
00
04

28
40
38
48

1F
82
60
00

00
00
00
00

03
F8
01
F4

lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0x40FF
beq
loc_118920
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118920:

# CODE XREF: check3+1D8j


clrlwi %r31, %r29, 24
cmplwi %r31, 2
bne
loc_118934
li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_118934:

# CODE XREF: check3+1ECj


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 0xD
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_11895C
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_11895C:

# CODE XREF: check3+214j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0xFC7
beq
loc_118970
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118970:

# CODE XREF: check3+228j


cmplwi %r31, 3
bne
error
li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_118980:

80
38
3B
38
38
48
60
54
41
38
48

DE
81
E0
60
A0
00
00
60
82
60
00

00
00
00
00
00
BE
00
04
00
00
00

00
38
00
04
00
35
00
3F
0C
00
C8

A0
28
40
3B
48

01
00
82
E0
00

00
1D
00
00
00

38
6A
0C
01
14

28
41
38
48

00
82
60
00

18
00
00
00

28
0C
00
A4

# CODE XREF: check3+B8j


# check3+C4j
%r6, dword_24B704
%r4, %sp, 0x50+var_18
%r31, 0
%r3, 4
%r5, 0
.RBEREAD

lwz
addi
li
li
li
bl
nop
clrlwi. %r0, %r3, 16
beq
loc_1189AC
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1189AC:

# CODE XREF: check3+264j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0xAED0
bne
loc_1189C0
li
%r31, 1
b
loc_1189D0
# --------------------------------------------------------------------------loc_1189C0:

# CODE XREF: check3+278j


cmplwi %r0, 0x2818
beq
loc_1189D0
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1189D0:

57 A0 06 3E

# CODE XREF: check3+280j


# check3+288j
clrlwi

%r0, %r29, 24

219

7.1.
seg000:001189D4
seg000:001189D8
seg000:001189DC
seg000:001189E0
seg000:001189E4
seg000:001189E8
seg000:001189EC
seg000:001189F0
seg000:001189F0
seg000:001189F0
seg000:001189F0
seg000:001189F4
seg000:001189F8
seg000:001189F8
seg000:001189F8
seg000:001189F8
seg000:001189FC
seg000:00118A00
seg000:00118A04
seg000:00118A08
seg000:00118A0C
seg000:00118A10
seg000:00118A14
seg000:00118A18
seg000:00118A1C
seg000:00118A20
seg000:00118A20
seg000:00118A20
seg000:00118A20
seg000:00118A24
seg000:00118A28
seg000:00118A2C
seg000:00118A30
seg000:00118A34
seg000:00118A34
seg000:00118A34
seg000:00118A34
seg000:00118A38
seg000:00118A3C
seg000:00118A40
seg000:00118A44
seg000:00118A44
seg000:00118A44
seg000:00118A44
seg000:00118A44
seg000:00118A48
seg000:00118A4C
seg000:00118A50
seg000:00118A54
seg000:00118A58
seg000:00118A5C
seg000:00118A60
seg000:00118A64
seg000:00118A64
seg000:00118A64
seg000:00118A64
seg000:00118A68
seg000:00118A6C
seg000:00118A6C
seg000:00118A6C
seg000:00118A6C
seg000:00118A6C
seg000:00118A70
seg000:00118A70
seg000:00118A70
seg000:00118A70
seg000:00118A74
seg000:00118A78
seg000:00118A7C
seg000:00118A80
seg000:00118A84
seg000:00118A88
seg000:00118A88

7.
28
40
57
41
48
60
48

00
82
E0
82
00
00
00

00
00
06
00
4C
00
00

02
20
3F
10
69
00
84

cmplwi %r0, 2
bne
loc_1189F8
clrlwi. %r0, %r31, 24
beq
good2
bl
sub_11D64C
nop
b
exit
# --------------------------------------------------------------------------good2:

38 60 00 01
48 00 00 7C

# CODE XREF: check3+2A4j


li
%r3, 1
b
exit
# --------------------------------------------------------------------------loc_1189F8:

80
38
38
38
48
60
54
41
38
48

DE
81
60
A0
00
00
60
82
60
00

00
00
00
00
BD
00
04
00
00
00

00
38
05
00
C1
00
3F
0C
00
54

A0
28
40
3B
48

01
00
82
E0
00

00
11
00
00
00

38
D3
0C
01
14

28
41
38
48

00
82
60
00

1A
00
00
00

EB
0C
00
30

# CODE XREF: check3+29Cj


lwz
%r6, dword_24B704
addi
%r4, %sp, 0x50+var_18
li
%r3, 5
li
%r5, 0
bl
.RBEREAD
nop
clrlwi. %r0, %r3, 16
beq
loc_118A20
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_118A20:

# CODE XREF: check3+2D8j


lhz
%r0, 0x50+var_18(%sp)
cmplwi %r0, 0xD300
bne
loc_118A34
li
%r31, 1
b
good1
# --------------------------------------------------------------------------loc_118A34:

# CODE XREF: check3+2ECj


cmplwi %r0, 0xEBA1
beq
good1
li
%r3, 0
b
exit
# --------------------------------------------------------------------------good1:

57
28
40
57
41
48
60
48

A0
00
82
E0
82
00
00
00

06
00
00
06
00
4B
00
00

3E
03
20
3F
10
F5
00
10

# CODE XREF: check3+2F4j


# check3+2FCj

clrlwi %r0, %r29, 24


cmplwi %r0, 3
bne
error
clrlwi. %r0, %r31, 24
beq
good
bl
sub_11D64C
nop
b
exit
# --------------------------------------------------------------------------good:

38 60 00 01
48 00 00 08

# CODE XREF: check3+318j


li
%r3, 1
b
exit
# --------------------------------------------------------------------------error:

38 60 00 00

# CODE XREF: check3+19Cj


# check3+238j ...
li

%r3, 0

exit:
80
38
83
7C
83
83
4E

01
21
E1
08
C1
A1
80

00
00
FF
03
FF
FF
00

58
50
FC
A6
F8
F4
20

# CODE XREF: check3+44j


# check3+58j ...
%r0, 0x50+arg_8(%sp)
%sp, %sp, 0x50
%r31, var_4(%sp)
%r0
%r30, var_8(%sp)
%r29, var_C(%sp)

lwz
addi
lwz
mtlr
lwz
lwz
blr
# End of function check3

.RBEREAD(). - - ,
CMPLWI.
220

7.1.
7.
r3 .RBEREAD() :
0, 1, 8, 0xA, 0xB, 0xC, 0xD, 4, 5. - ?
, , -, Sentinel Eve3!
PowerPC: -
.RBEREAD(), 1
0 .
: check1() 1 .
PowerPC, check2
0x001186FC 0x00118718.
0x001186FC 0x48 0 BEQ B
( ): [10].
0x00118718 0x60 3 ,
NOP: .
, IDA .

7.1.2

#2: SCO OpenServer

SCO OpenServer 1997 .


, : Copyright
1989, Rainbow Technologies, Inc., Irvine, CA Sentinel Integrated Driver Ver. 3.0 .
, /dev :
/dev/rbsl8
/dev/rbsl9
/dev/rbsl10

, ,
.
IDA, COFF SCO
OpenServer.
rbsl , , :
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB8
.text:00022AB9
.text:00022ABB
.text:00022ABE
.text:00022ABF
.text:00022AC4
.text:00022AC5
.text:00022AC8
.text:00022AC9
.text:00022ACA
.text:00022ACF
.text:00022AD2
.text:00022AD7
.text:00022ADD
.text:00022ADE
.text:00022AE1
.text:00022AE4
.text:00022AE9
.text:00022AEF
.text:00022AF4
.text:00022AFA
.text:00022AFF
.text:00022B01
.text:00022B04
.text:00022B07
.text:00022B0C

SSQC

public SSQC
proc near

var_44
var_29
arg_0

= byte ptr -44h


= byte ptr -29h
= dword ptr 8
push
mov
sub
push
mov
push
mov
push
push
call
add
cmp
jnz
inc
mov
movsx
cmp
jz
cmp
jz
cmp
jnz
movsx
sub
mov
add

; CODE XREF: SSQ+7p

ebp
ebp, esp
esp, 44h
edi
edi, offset unk_4035D0
esi
esi, [ebp+arg_0]
ebx
esi
strlen
esp, 4
eax, 2
loc_22BA4
esi
al, [esi-1]
eax, al
eax, 3
loc_22B84
eax, 4
loc_22B94
eax, 5
short loc_22B6B
ebx, byte ptr [esi]
ebx, 0
eax, 7
eax, ebx

221

7.1.
.text:00022B0E
.text:00022B0F
.text:00022B12
.text:00022B17
.text:00022B18
.text:00022B1D
.text:00022B1F
.text:00022B24
.text:00022B29
.text:00022B2C
.text:00022B31
.text:00022B33
.text:00022B36
.text:00022B37
.text:00022B3A
.text:00022B3F
.text:00022B40
.text:00022B45
.text:00022B48
.text:00022B48
.text:00022B48
.text:00022B4A
.text:00022B4C
.text:00022B4E
.text:00022B4F
.text:00022B54
.text:00022B57
.text:00022B57
.text:00022B57
.text:00022B59
.text:00022B5C
.text:00022B5D
.text:00022B62
.text:00022B65
.text:00022B67
.text:00022B69
.text:00022B6B
.text:00022B6B
.text:00022B6B
.text:00022B70
.text:00022B71
.text:00022B72
.text:00022B73
.text:00022B75
.text:00022B76
.text:00022B76
.text:00022B77
.text:00022B78
.text:00022B78
.text:00022B78
.text:00022B79
.text:00022B7A
.text:00022B7B
.text:00022B7D
.text:00022B7F
.text:00022B80
.text:00022B80
.text:00022B81
.text:00022B84
.text:00022B84
.text:00022B84
.text:00022B86
.text:00022B87
.text:00022B88
.text:00022B89
.text:00022B8E
.text:00022B90
.text:00022B92
.text:00022B93
.text:00022B94
.text:00022B94
.text:00022B94
.text:00022B94
.text:00022B96
.text:00022B97
.text:00022B98

7.
push
lea
push
push
call
push
push
call
add
cmp
jz
lea
push
lea
push
push
call
add

eax
eax, [ebp+var_44]
offset aDevSlD ; "/dev/sl%d"
eax
nl_sprintf
0
; int
offset aDevRbsl8 ; char *
_access
esp, 14h
eax, 0FFFFFFFFh
short loc_22B48
eax, [ebx+7]
eax
eax, [ebp+var_44]
offset aDevRbslD ; "/dev/rbsl%d"
eax
nl_sprintf
esp, 0Ch

mov
test
jle
push
call
add

; CODE XREF: SSQC+79j


edx, [edi]
edx, edx
short loc_22B57
edx
; int
_close
esp, 4

push
lea
push
call
add
test
mov
jge

; CODE XREF: SSQC+94j


2
; int
eax, [ebp+var_44]
eax
; char *
_open
esp, 8
eax, eax
[edi], eax
short loc_22B78

loc_22B48:

loc_22B57:

loc_22B6B:

; CODE XREF: SSQC+47j


mov
eax, 0FFFFFFFFh
pop
ebx
pop
esi
pop
edi
mov
esp, ebp
pop
ebp
retn
; --------------------------------------------------------------------------align 4
loc_22B78:

; CODE XREF: SSQC+B1j


pop
ebx
pop
esi
pop
edi
xor
eax, eax
mov
esp, ebp
pop
ebp
retn
; --------------------------------------------------------------------------align 4
loc_22B84:

; CODE XREF: SSQC+31j


mov
al, [esi]
pop
ebx
pop
esi
pop
edi
mov
ds:byte_407224, al
mov
esp, ebp
xor
eax, eax
pop
ebp
retn
; --------------------------------------------------------------------------loc_22B94:

; CODE XREF: SSQC+3Cj


mov
pop
pop
pop

al, [esi]
ebx
esi
edi

222

7.1.
.text:00022B99
.text:00022B9E
.text:00022BA0
.text:00022BA2
.text:00022BA3
.text:00022BA4
.text:00022BA4
.text:00022BA4
.text:00022BA4
.text:00022BAB
.text:00022BAC
.text:00022BAD
.text:00022BB4
.text:00022BB5
.text:00022BB8
.text:00022BBD
.text:00022BBE
.text:00022BC3
.text:00022BC6
.text:00022BC7
.text:00022BCC
.text:00022BCF
.text:00022BD4
.text:00022BD6
.text:00022BDA
.text:00022BDA
.text:00022BDA
.text:00022BDD
.text:00022BDE
.text:00022BE3
.text:00022BE4
.text:00022BE7
.text:00022BE8
.text:00022BEA
.text:00022BEB
.text:00022BF0
.text:00022BF3
.text:00022BF4
.text:00022BF5
.text:00022BF6
.text:00022BF8
.text:00022BF9
.text:00022BF9
.text:00022BFA
.text:00022BFA

7.
mov
ds:byte_407225, al
mov
esp, ebp
xor
eax, eax
pop
ebp
retn
; --------------------------------------------------------------------------loc_22BA4:
movsx
push
push
movsx
push
lea
push
push
call
lea
push
call
add
cmp
jle
mov

; CODE XREF: SSQC+1Fj


eax, ds:byte_407225
esi
eax
eax, ds:byte_407224
eax
eax, [ebp+var_44]
offset a46CCS
; "46%c%c%s"
eax
nl_sprintf
eax, [ebp+var_44]
eax
strlen
esp, 18h
eax, 1Bh
short loc_22BDA
[ebp+var_29], 0

loc_22BDA:

; CODE XREF: SSQC+11Cj


lea
eax, [ebp+var_44]
push
eax
call
strlen
push
eax
; unsigned int
lea
eax, [ebp+var_44]
push
eax
; void *
mov
eax, [edi]
push
eax
; int
call
_write
add
esp, 10h
pop
ebx
pop
esi
pop
edi
mov
esp, ebp
pop
ebp
retn
; --------------------------------------------------------------------------db 0Eh dup(90h)
SSQC
endp

, - .
- SSQC() thunk function:
.text:0000DBE8
.text:0000DBE8
.text:0000DBE8
.text:0000DBE8
.text:0000DBE8
.text:0000DBE8
.text:0000DBE8
.text:0000DBE9
.text:0000DBEB
.text:0000DBEE
.text:0000DBEF
.text:0000DBF4
.text:0000DBF7
.text:0000DBF9
.text:0000DBFA
.text:0000DBFA
.text:0000DBFB
.text:0000DBFB

SSQ

public SSQ
proc near

arg_0

= dword ptr

; CODE XREF: sys_info+A9p


; sys_info+CBp ...
8

push
ebp
mov
ebp, esp
mov
edx, [ebp+arg_0]
push
edx
call
SSQC
add
esp, 4
mov
esp, ebp
pop
ebp
retn
; --------------------------------------------------------------------------align 4
SSQ
endp

SSQ() -.
:
.data:0040169C _51_52_53
.data:0040169C
.data:0040169C
.data:004016A0
.data:004016A4

dd offset aPressAnyKeyT_0
;
;
dd offset a51
;
dd offset a52
;

223

; DATA XREF: init_sys+392r


sys_info+A1r
"PRESS ANY KEY TO CONTINUE: "
"51"
"52"

7.1.

7.

.data:004016A8

dd offset a53

; "53"

dd offset a3c

; DATA XREF: sys_info:loc_D67Br


; "3C"
; "3E"

...
.data:004016B8 _3C_or_3E
.data:004016B8
.data:004016BC

dd offset a3e

; these names I gave to the labels:


.data:004016C0 answers1
dd 6B05h
.data:004016C4
dd 3D87h
.data:004016C8 answers2
dd 3Ch
.data:004016CC
dd 832h
.data:004016D0 _C_and_B
db 0Ch
.data:004016D0
.data:004016D1 byte_4016D1
db 0Bh
.data:004016D2
db
0

; DATA XREF: sys_info+E7r


; DATA XREF: sys_info+F2r
; DATA XREF: sys_info+BAr
; sys_info:OKr
; DATA XREF: sys_info+FDr

...
.text:0000D652
.text:0000D654
.text:0000D659
.text:0000D660
.text:0000D661
.text:0000D666
.text:0000D669
.text:0000D66E
.text:0000D670
.text:0000D672
.text:0000D677
.text:0000D679
.text:0000D67B
.text:0000D67B
.text:0000D67B
.text:0000D682
.text:0000D683
.text:0000D688
.text:0000D68D
.text:0000D692
.text:0000D697
.text:0000D69C
.text:0000D69F
.text:0000D6A6
.text:0000D6A8
.text:0000D6AA
.text:0000D6B1
.text:0000D6B3
.text:0000D6B5
.text:0000D6BB
.text:0000D6BC
.text:0000D6BE
.text:0000D6C0
.text:0000D6C0
.text:0000D6C0
.text:0000D6C6
.text:0000D6C8
.text:0000D6CD
.text:0000D6CF
.text:0000D6D1
.text:0000D6D1
.text:0000D6D1
.text:0000D6D1
.text:0000D6D4
.text:0000D6D5
.text:0000D6D8
.text:0000D6DB
.text:0000D6E1
.text:0000D6E1
.text:0000D6E1
.text:0000D6E1
.text:0000D6E2
.text:0000D6E3
.text:0000D6E5
.text:0000D6E6
.text:0000D6E6

xor
mov
mov
push
call
add
cmp
jz
xor
mov
test
jz

eax, eax
al, ds:ctl_port
ecx, _51_52_53[eax*4]
ecx
SSQ
esp, 4
eax, 0FFFFFFFFh
short loc_D6D1
ebx, ebx
al, _C_and_B
al, al
short loc_D6C0

mov
push
call
push
call
push
call
add
mov
cmp
jz
mov
cmp
jz
mov
inc
test
jnz

; CODE XREF: sys_info+106j


eax, _3C_or_3E[ebx*4]
eax
SSQ
offset a4g
; "4G"
SSQ
offset a0123456789 ; "0123456789"
SSQ
esp, 0Ch
edx, answers1[ebx*4]
eax, edx
short OK
ecx, answers2[ebx*4]
eax, ecx
short OK
al, byte_4016D1[ebx]
ebx
al, al
short loc_D67B

inc
xor
mov
cmp
jle

ds:ctl_port
eax, eax
al, ds:ctl_port
eax, edi
short loc_D652

loc_D67B:

loc_D6C0:

; CODE XREF: sys_info+C1j

loc_D6D1:

; CODE XREF: sys_info+98j


; sys_info+B6j
mov
inc
mov
cmp
jle

loc_D6E1:

edx, [ebp+var_8]
edx
[ebp+var_8], edx
edx, 3
loc_D641
; CODE XREF: sys_info+16j
; sys_info+51j ...

pop
ebx
pop
edi
mov
esp, ebp
pop
ebp
retn
; ---------------------------------------------------------------------------

224

7.1.

7.

.text:0000D6E7
.text:0000D6E8
.text:0000D6E8 OK:
.text:0000D6E8
.text:0000D6E8
.text:0000D6EE
.text:0000D6EF
.text:0000D6F0
.text:0000D6F5
.text:0000D6F7
.text:0000D6F8
.text:0000D6F8 sys_info

align 4

mov
pop
pop
mov
mov
pop
retn
endp

; CODE XREF: sys_info+F0j


; sys_info+FBj
al, _C_and_B[ebx]
ebx
edi
ds:ctl_model, al
esp, ebp
ebp

3C 3E : - Sentinel Pro Rainbow , - -.


-? CRC32,
, . , : , CRC32 32 . CRC32 : ,
. - . - MD5, SHA1,
, . :
(
), . , -
, c ,
c . .
.

.
. . ( - SSQC()) 16- . ,
.
, ,
. ,
-:
.
.
51/52/53 LPT-. 3x/4x
family Sentinel Pro :
LPT-.
- "0123456789".
. , 0xC 0xB
ctl_model.
: "PRESS ANY KEY TO CONTINUE: .
, . ( :
.)
, ctl_mode.
:
.text:0000D708
.text:0000D708
.text:0000D708
.text:0000D708
.text:0000D708
.text:0000D708
.text:0000D708
.text:0000D708

prep_sys

proc near

var_14
var_10
var_8
var_2

=
=
=
=

; CODE XREF: init_sys+46Ap

dword ptr -14h


byte ptr -10h
dword ptr -8
word ptr -2

push

ebp

225

7.1.

7.

.text:0000D709
.text:0000D70E
.text:0000D710
.text:0000D713
.text:0000D715
.text:0000D717
.text:0000D71C
.text:0000D71E
.text:0000D720
.text:0000D727
.text:0000D72C

mov
mov
sub
test
jnz
mov
test
jnz
mov
mov
jmp

eax, ds:net_env
ebp, esp
esp, 1Ch
eax, eax
short loc_D734
al, ds:ctl_model
al, al
short loc_D77E
[ebp+var_8], offset aIeCvulnvvOkgT_ ; "Ie-cvulnvV\\\bOKG]T_"
edx, 7
loc_D7E7

...
.text:0000D7E7 loc_D7E7:
.text:0000D7E7
.text:0000D7E7
.text:0000D7E8
.text:0000D7EB
.text:0000D7ED
.text:0000D7EE
.text:0000D7F0
.text:0000D7F5
.text:0000D7FA
.text:0000D7FF

; CODE XREF: prep_sys+24j


; prep_sys+33j
push
mov
push
push
push
call
push
call
call

edx
edx, [ebp+var_8]
20h
edx
16h
err_warn
offset station_sem
ClosSem
startup_err

0, -
.
- XOR4 :
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43C
.text:0000A43D
.text:0000A43F
.text:0000A442
.text:0000A443
.text:0000A446
.text:0000A448
.text:0000A44A
.text:0000A44B
.text:0000A44D
.text:0000A450
.text:0000A453
.text:0000A453
.text:0000A453
.text:0000A455
.text:0000A458
.text:0000A45A
.text:0000A45D
.text:0000A45E
.text:0000A460
.text:0000A464
.text:0000A466
.text:0000A466
.text:0000A466
.text:0000A46B
.text:0000A46E
.text:0000A473
.text:0000A475
.text:0000A478
.text:0000A479
.text:0000A47E
.text:0000A481
.text:0000A481
.text:0000A481
4

err_warn

proc near

var_55
var_54
arg_0
arg_4
arg_8
arg_C

=
=
=
=
=
=

; CODE XREF: prep_sys+E8p


; prep_sys2+2Fp ...

byte ptr -55h


byte ptr -54h
dword ptr 8
dword ptr 0Ch
dword ptr 10h
dword ptr 14h

push
mov
sub
push
mov
xor
test
push
jle
mov
mov

ebp
ebp, esp
esp, 54h
edi
ecx, [ebp+arg_8]
edi, edi
ecx, ecx
esi
short loc_A466
esi, [ebp+arg_C]
edx, [ebp+arg_4]

xor
mov
xor
add
inc
cmp
mov
jl

; CODE XREF: err_warn+28j


eax, eax
al, [edx+edi]
eax, esi
esi, 3
edi
edi, ecx
[ebp+edi+var_55], al
short loc_A453

mov
mov
cmp
jnz
lea
push
call
add

; CODE XREF: err_warn+Fj


[ebp+edi+var_54], 0
eax, [ebp+arg_0]
eax, 18h
short loc_A49C
eax, [ebp+var_54]
eax
status_line
esp, 4

push

50h

loc_A453:

loc_A466:

loc_A481:

; CODE XREF: err_warn+72j

eXclusive OR ( )

226

7.1.

7.

.text:0000A483
push
0
.text:0000A485
lea
eax, [ebp+var_54]
.text:0000A488
push
eax
.text:0000A489
call
memset
.text:0000A48E
call
pcv_refresh
.text:0000A493
add
esp, 0Ch
.text:0000A496
pop
esi
.text:0000A497
pop
edi
.text:0000A498
mov
esp, ebp
.text:0000A49A
pop
ebp
.text:0000A49B
retn
.text:0000A49C ; --------------------------------------------------------------------------.text:0000A49C
.text:0000A49C loc_A49C:
; CODE XREF: err_warn+37j
.text:0000A49C
push
0
.text:0000A49E
lea
eax, [ebp+var_54]
.text:0000A4A1
mov
edx, [ebp+arg_0]
.text:0000A4A4
push
edx
.text:0000A4A5
push
eax
.text:0000A4A6
call
pcv_lputs
.text:0000A4AB
add
esp, 0Ch
.text:0000A4AE
jmp
short loc_A481
.text:0000A4AE err_warn
endp

,
, .
- offln
0xFE81 0x12A9. , - - timer() (
?), .
.text:0000DA55
.text:0000DA55
.text:0000DA5A
.text:0000DA5F
.text:0000DA62
.text:0000DA64
.text:0000DA66
.text:0000DA69
.text:0000DA6B
.text:0000DA71
.text:0000DA77
.text:0000DA7D
.text:0000DA83
.text:0000DA83
.text:0000DA83
.text:0000DA85
.text:0000DA88
.text:0000DA8A
.text:0000DA90
.text:0000DA96
.text:0000DA99
.text:0000DA9F
.text:0000DA9F
.text:0000DA9F
.text:0000DAA2
.text:0000DAA4
.text:0000DAA6
.text:0000DAA8
.text:0000DAAD
.text:0000DAB0
.text:0000DAB0
.text:0000DAB0
.text:0000DAB1
.text:0000DAB4
.text:0000DAB6
.text:0000DABB
.text:0000DABD

loc_DA55:
push
call
add
mov
mov
cmp
jnz
cmp
jz
cmp
jz

; CODE XREF: sync_sys+24Cj


offset aOffln
; "offln"
SSQ
esp, 4
dl, [ebx]
esi, eax
dl, 0Bh
short loc_DA83
esi, 0FE81h
OK
esi, 0FFFFF8EFh
OK

mov
cmp
jnz
cmp
jz
cmp
jz

cl, [ebx]
cl, 0Ch
short loc_DA9F
esi, 12A9h
OK
esi, 0FFFFFFF5h
OK

mov
test
jz
push
call
add

; CODE XREF: sync_sys+220j


eax, [ebp+var_18]
eax, eax
short loc_DAB0
24h
timer
esp, 4

inc
cmp
jle
mov
test
jz

edi
edi, 3
short loc_DA55
eax, ds:net_env
eax, eax
short error

mov
mov

; CODE XREF: sync_sys+255j


; sync_sys+274j ...
[ebp+var_8], offset encrypted_error_message2
[ebp+var_C], 17h

loc_DA83:

; CODE XREF: sync_sys+201j

loc_DA9F:

loc_DAB0:

; CODE XREF: sync_sys+23Cj

...
.text:0000DAF7 error:
.text:0000DAF7
.text:0000DAF7
.text:0000DAFE

227

7.1.

7.

.text:0000DB05

jmp

decrypt_end_print_message

...
; this name I gave to label:
.text:0000D9B6 decrypt_end_print_message:
; CODE XREF: sync_sys+29Dj
.text:0000D9B6
; sync_sys+2ABj
.text:0000D9B6
mov
eax, [ebp+var_18]
.text:0000D9B9
test
eax, eax
.text:0000D9BB
jnz
short loc_D9FB
.text:0000D9BD
mov
edx, [ebp+var_C]
.text:0000D9C0
mov
ecx, [ebp+var_8]
.text:0000D9C3
push
edx
.text:0000D9C4
push
20h
.text:0000D9C6
push
ecx
.text:0000D9C7
push
18h
.text:0000D9C9
call
err_warn
.text:0000D9CE
push
0Fh
.text:0000D9D0
push
190h
.text:0000D9D5
call
sound
.text:0000D9DA
mov
[ebp+var_18], 1
.text:0000D9E1
add
esp, 18h
.text:0000D9E4
call
pcv_kbhit
.text:0000D9E9
test
eax, eax
.text:0000D9EB
jz
short loc_D9FB
...
; this name I gave to label:
.data:00401736 encrypted_error_message2 db 74h, 72h, 78h, 43h, 48h, 6, 5Ah, 49h, 4Ch, 2 dup(47h)
.data:00401736
; DATA XREF: sync_sys:erroro
.data:00401736
db 51h, 4Fh, 47h, 61h, 20h, 22h, 3Ch, 24h, 33h, 36h, 76h
.data:00401736
db 3Ah, 33h, 31h, 0Ch, 0, 0Bh, 1Fh, 7, 1Eh, 1Ah

: CMP .
SCO OpenServer.

7.1.3

#3: MS-DOS

MS-DOS 1995 .
DOS-, MS-DOS 8086
80286, 16-. 16- ,
, 16-, .
MS-DOS , ,
OUT/IN,
( OS user mode).
, MS-DOS LPT- . . , :
seg030:0034
seg030:0034
seg030:0034
seg030:0034
seg030:0034
seg030:0034
seg030:0035
seg030:0037
seg030:003B
seg030:003E
seg030:003F
seg030:0040
seg030:0040

out_port

proc far

arg_0

= byte ptr

out_port

push
mov
mov
mov
out
pop
retf
endp

55
8B EC
8B 16 7E E7
8A 46 06
EE
5D
CB

bp
bp,
dx,
al,
dx,
bp

; CODE XREF: sent_pro+22p


; sent_pro+2Ap ...
6

sp
_out_port ; 0x378
[bp+arg_0]
al

( ).
out_port() -:
seg030:0041
seg030:0041

sent_pro

proc far

; CODE XREF: check_dongle+34p

228

7.1.
seg030:0041
seg030:0041
seg030:0041
seg030:0041
seg030:0041
seg030:0045
seg030:0046
seg030:0047
seg030:004B
seg030:004C
seg030:004E
seg030:0051
seg030:0054
seg030:0056
seg030:0059
seg030:005C
seg030:005E
seg030:005F
seg030:0062
seg030:0063
seg030:0066
seg030:0067
seg030:006A
seg030:006B
seg030:006E
seg030:006F
seg030:0071
seg030:0073
seg030:0073
seg030:0073
seg030:0073
seg030:0074
seg030:0074
seg030:0074
seg030:0078
seg030:007A
seg030:007D
seg030:007E
seg030:0081
seg030:0082
seg030:0085
seg030:0086
seg030:0089
seg030:008A
seg030:008D
seg030:008E
seg030:0091
seg030:0092
seg030:0095
seg030:0096
seg030:0099
seg030:009A
seg030:009D
seg030:009E
seg030:00A1
seg030:00A2
seg030:00A5
seg030:00A6
seg030:00A9
seg030:00AA
seg030:00AD
seg030:00AF
seg030:00AF
seg030:00AF
seg030:00AF
seg030:00B2
seg030:00B2
seg030:00B2
seg030:00B4
seg030:00B8
seg030:00B9
seg030:00BB
seg030:00BD
seg030:00C0
seg030:00C0
seg030:00C0

7.
var_3
var_2
arg_0

C8
56
57
8B
EC
8A
80
80
8A
88
80
8A
EE
68
0E
E8
59
68
0E
E8
59
33
EB

= byte ptr -3
= word ptr -2
= dword ptr 6

04 00 00

enter
4, 0
push
si
push
di
16 82 E7
mov
dx, _in_port_1 ; 0x37A
in
al, dx
D8
mov
bl, al
E3 FE
and
bl, 0FEh
CB 04
or
bl, 4
C3
mov
al, bl
46 FD
mov
[bp+var_3], al
E3 1F
and
bl, 1Fh
C3
mov
al, bl
out
dx, al
FF 00
push
0FFh
push
cs
CE FF
call
near ptr out_port
pop
cx
D3 00
push
0D3h
push
cs
C6 FF
call
near ptr out_port
pop
cx
F6
xor
si, si
01
jmp
short loc_359D4
; --------------------------------------------------------------------------loc_359D3:

46

; CODE XREF: sent_pro+37j


inc

si

loc_359D4:
81
7C
68
0E
E8
59
68
0E
E8
59
68
0E
E8
59
68
0E
E8
59
68
0E
E8
59
68
0E
E8
59
BF
EB

; CODE XREF: sent_pro+30j


cmp
si, 96h
jl
short loc_359D3
push
0C3h
push
cs
call
near ptr out_port
pop
cx
push
0C7h
push
cs
call
near ptr out_port
pop
cx
push
0D3h
push
cs
call
near ptr out_port
pop
cx
push
0C3h
push
cs
call
near ptr out_port
pop
cx
push
0C7h
push
cs
call
near ptr out_port
pop
cx
push
0D3h
push
cs
call
near ptr out_port
pop
cx
mov
di, 0FFFFh
jmp
short loc_35A4F
; ---------------------------------------------------------------------------

FE 96 00
F9
C3 00
B3 FF
C7 00
AB FF
D3 00
A3 FF
C3 00
9B FF
C7 00
93 FF
D3 00
8B FF
FF FF
40

loc_35A0F:
BE 04 00

; CODE XREF: sent_pro+BDj


mov

si, 4

shl
mov
in
test
jnz
or

; CODE XREF: sent_pro+ACj


di, 1
dx, _in_port_2 ; 0x379
al, dx
al, 80h
short loc_35A20
di, 1

test

[bp+var_2], 8

loc_35A12:
D1
8B
EC
A8
75
83

E7
16 80 E7
80
03
CF 01
loc_35A20:

F7 46 FE 08+

; CODE XREF: sent_pro+7Aj

229

7.1.
seg030:00C5
seg030:00C7
seg030:00CA
seg030:00CC
seg030:00CC
seg030:00CC
seg030:00CC
seg030:00CF
seg030:00D0
seg030:00D3
seg030:00D4
seg030:00D7
seg030:00D7
seg030:00D7
seg030:00D8
seg030:00DB
seg030:00DC
seg030:00DF
seg030:00E0
seg030:00E3
seg030:00E4
seg030:00E7
seg030:00E9
seg030:00EC
seg030:00ED
seg030:00EF
seg030:00EF
seg030:00EF
seg030:00F2
seg030:00F5
seg030:00F8
seg030:00F9
seg030:00FC
seg030:00FE
seg030:0100
seg030:0103
seg030:0104
seg030:0107
seg030:0108
seg030:010C
seg030:010D
seg030:010F
seg030:0112
seg030:0114
seg030:0115
seg030:0116
seg030:0118
seg030:011B
seg030:011D
seg030:0120
seg030:0123
seg030:0125
seg030:0125
seg030:0125
seg030:0125
seg030:0128
seg030:0128
seg030:0128
seg030:012B
seg030:012D
seg030:0130
seg030:0130
seg030:0130
seg030:0134
seg030:0136
seg030:0137
seg030:0139
seg030:013A
seg030:013B
seg030:013C
seg030:013C

7.

74 05
68 D7 00
EB 0B

jz
short loc_35A2C
push
0D7h ; +
jmp
short loc_35A37
; --------------------------------------------------------------------------loc_35A2C:

68 C3 00
0E
E8 61 FF
59
68 C7 00

push
push
call
pop
push

; CODE XREF: sent_pro+84j


0C3h
cs
near ptr out_port
cx
0C7h

push
call
pop
push
push
call
pop
mov
shl
mov
dec
jnz

; CODE XREF: sent_pro+89j


cs
near ptr out_port
cx
0D3h
cs
near ptr out_port
cx
ax, [bp+var_2]
ax, 1
[bp+var_2], ax
si
short loc_35A12

loc_35A37:
0E
E8
59
68
0E
E8
59
8B
D1
89
4E
75

59 FF
D3 00
51 FF
46 FE
E0
46 FE
C3
loc_35A4F:

C4
FF
26
98
89
0B
75
68
0E
E8
59
8B
EC
8A
80
8A
EE
EC
8A
F6
74
8A
80
EB

; CODE XREF: sent_pro+6Cj


les
bx, [bp+arg_0]
inc
word ptr [bp+arg_0]
mov
al, es:[bx]
cbw
46 FE
mov
[bp+var_2], ax
C0
or
ax, ax
AF
jnz
short loc_35A0F
FF 00
push
0FFh
push
cs
2D FF
call
near ptr out_port
pop
cx
16 82 E7
mov
dx, _in_port_1 ; 0x37A
in
al, dx
C8
mov
cl, al
E1 5F
and
cl, 5Fh
C1
mov
al, cl
out
dx, al
in
al, dx
C8
mov
cl, al
C1 20
test
cl, 20h
08
jz
short loc_35A85
5E FD
mov
bl, [bp+var_3]
E3 DF
and
bl, 0DFh
03
jmp
short loc_35A88
; --------------------------------------------------------------------------5E 06
46 06
8A 07

loc_35A85:
8A 5E FD

; CODE XREF: sent_pro+DAj


mov

bl, [bp+var_3]

test
jz
and

cl, 80h
short loc_35A90
bl, 7Fh

mov
mov
out
mov
pop
pop
leave
retf
endp

dx,
al,
dx,
ax,
di
si

loc_35A88:
F6 C1 80
74 03
80 E3 7F

; CODE XREF: sent_pro+E2j

loc_35A90:
8B 16 82 E7
8A C3
EE
8B C7
5F
5E
C9
CB
sent_pro

; CODE XREF: sent_pro+EAj


_in_port_1 ; 0x37A
bl
al
di

Sentinel Pro .
, 16- .
Sentinel Pro . 0x378, ..,
230

7.1.
7.
, USB . , , -
5 .
0x379, paper out, ack, busy
, , .
- , .
_in_port_2 (0x379) _in_port_1
(0x37A).
, busy seg030:00B9:
DI -.
? . , .
, : .
- :
00000000
00000000
00000019
0000001B

struct_0
field_0
_A
struct_0

struc ; (sizeof=0x1B)
db 25 dup(?)
dw ?
ends

dseg:3CBC 61 63 72 75+_Q
dseg:3CBC 6E 00 00 00+

; string(C)

struct_0 <hello, 01122h>


; DATA XREF: check_dongle+2Eo

... skipped ...


dseg:3E00
dseg:3E1B
dseg:3E36
dseg:3E51
dseg:3E6C
dseg:3E87
dseg:3EA2
dseg:3EBD

63
64
63
70
63
63
64
63

seg030:0145
seg030:0145
seg030:0145
seg030:0145
seg030:0145
seg030:0145
seg030:0149
seg030:014A
seg030:014D
seg030:014F
seg030:0154
seg030:0155
seg030:0156
seg030:0158
seg030:015B
seg030:015F
seg030:0164
seg030:0166
seg030:0168
seg030:0169
seg030:016A
seg030:016D
seg030:016E
seg030:0170
seg030:0173
seg030:0176
seg030:0177
seg030:0178
seg030:0179
seg030:017C
seg030:017F
seg030:0182
seg030:0184
seg030:0187

6F
6F
61
61
6F
6C
69
6F

C8
56
66
6A
9A
52
50
66
83
66
66
7E
6A
90
0E
E8
59
8B
6B
05
1E
50
0E
E8
83
89
8B
6B
66

66
67
74
70
6B
6F
72
70

66+
00+
00+
65+
65+
63+
00+
79+

struct_0
struct_0
struct_0
struct_0
struct_0
struct_0
struct_0
struct_0

check_dongle

proc far

var_6
var_2

= dword ptr -6
= word ptr -2

06 00 00
6A 00
00
C1 18 00+

58
C4 06
89 46 FA
3B 06 D8+
44
14

52 00
F0
C0 1B
BC 3C

C5
C4
46
C6
C0
0F

FE
04
FE
12
BF C0

<coffee, 7EB7h>
<dog, 0FFADh>
<cat, 0FF5Fh>
<paper, 0FFDFh>
<coke, 0F568h>
<clock, 55EAh>
<dir, 0FFAEh>
<copy, 0F557h>

enter
push
push
push
call
push
push
pop
add
mov
cmp
jle
push
nop
push
call
pop
mov
imul
add
push
push
push
call
add
mov
mov
imul
movsx

; CODE XREF: sub_3771D+3EP

6, 0
si
large 0
; newtime
0
; cmd
_biostime
dx
ax
eax
sp, 6
[bp+var_6], eax
eax, _expiration
short loc_35B0A
14h
cs
near ptr get_rand
cx
si, ax
ax, 1Bh
ax, offset _Q
ds
ax
cs
near ptr sent_pro
sp, 4
[bp+var_2], ax
ax, si
ax, 18
eax, ax

Centronics IEEE 1284


.

231

7.1.
seg030:018B
seg030:018F
seg030:0192
seg030:0197
seg030:0199
seg030:019C
seg030:01A0
seg030:01A3
seg030:01A5
seg030:01A8
seg030:01AA
seg030:01AA
seg030:01AA
seg030:01AA
seg030:01AA
seg030:01AC
seg030:01AC
seg030:01AC
seg030:01AD
seg030:01AE
seg030:01AE

66
66
66
8B
6B
8B
3B
74
B8
EB

7.
8B
03
89
DE
DB
87
46
05
01
02

56 FA
D0
16 D8+

mov
edx, [bp+var_6]
add
edx, eax
mov
_expiration, edx
mov
bx, si
1B
imul
bx, 27
D5 3C
mov
ax, _Q._A[bx]
FE
cmp
ax, [bp+var_2]
jz
short loc_35B0A
00
mov
ax, 1
jmp
short loc_35B0C
; --------------------------------------------------------------------------loc_35B0A:

33 C0

; CODE XREF: check_dongle+1Fj


; check_dongle+5Ej
xor

ax, ax

pop
leave
retf
endp

si

loc_35B0C:
5E
C9
CB
check_dongle

; CODE XREF: check_dongle+63j

- , ,
, - ( - -
MCU6 ),
, - biostime().
- get_rand() - :
seg030:01BF
seg030:01BF
seg030:01BF
seg030:01BF
seg030:01BF
seg030:01C0
seg030:01C2
seg030:01C7
seg030:01CB
seg030:01D0
seg030:01D4
seg030:01DA
seg030:01DC
seg030:01DF
seg030:01E0
seg030:01E0

55
8B
9A
66
66
66
66
66
66
5D
CB

EC
3D
0F
0F
0F
BB
99
F7

21
BF
BF
AF
00

get_rand

proc far

arg_0

= word ptr

00+
C0
56+
C2
80+

FB

get_rand

push
mov
call
movsx
movsx
imul
mov
cdq
idiv
pop
retf
endp

; CODE XREF: check_dongle+25p


6

bp
bp, sp
_rand
eax, ax
edx, [bp+arg_0]
eax, edx
ebx, 8000h
ebx
bp

, .
, , .
:
seg033:087B 9A 45 01
seg033:0880 0B C0
seg033:0882 74 62
seg033:0884 83 3E 60
seg033:0889 75 5B
seg033:088B FF 06 60
seg033:088F 1E
seg033:0890 68 22 44
Software Lock\n"
seg033:0893 1E
seg033:0894 68 60 E9
seg033:0897 9A 79 65
seg033:089C 83 C4 08
seg033:089F 1E
seg033:08A0 68 42 44
seg033:08A3 1E
seg033:08A4 68 60 E9
seg033:08A7 9A CD 64

96+

42+
42

00+

00+

call
or
jz
cmp
jnz
inc
push
push

check_dongle
ax, ax
short OK
word_620E0, 0
short OK
word_620E0
ds
offset aTrupcRequiresA ; "This Software Requires a

push
push
call
add
push
push
push
push
call

ds
offset byte_6C7E0 ; dest
_strcpy
sp, 8
ds
offset aPleaseContactA ; "Please Contact ..."
ds
offset byte_6C7E0 ; dest
_strcat

: - check_dongle()
0.
6

Microcontroller unit

232

7.1.
, :

7.

mov ax,0
retf

MS-DOS
- strcpy() 2 ,
4:
seg033:088F 1E
seg033:0890 68 22 44
Software Lock\n"
seg033:0893 1E
seg033:0894 68 60 E9
seg033:0897 9A 79 65 00+
seg033:089C 83 C4 08

push
push

ds
offset aTrupcRequiresA ; "This Software Requires a

push
push
call
add

ds
offset byte_6C7E0 ; dest
_strcpy
sp, 8

? , MS-DOS 8086.
8086/8088 16- , 20- (
1MB ).
RAM ( 640KB), ROM7 , , EMS-, .
8086/8088 8- 8080. 8080 16- , .., 64KB.
8 , 8086 64- , ,
. , - ,
. 8086 16-, , ,
(CS, DS, ES, SS) . 20-
( DS:BX)
_ = (_ 4) + _
, (EGA9 , VGA10 ) IBM PC-
64KB. , 0xA000 ,
, DS. DS:0 , DS:0xFFFF . 20- , 0xA0000 0xAFFFF.
0x1234, ,
, ,
.
, MS-DOS
, .., 16- . 20-
, , :
.
, - , 64KB.
, strcpy(), - (-) ,
16- .
. DS
, .
- sent_pro() seg030:00EF: LES
ES:BX . MOV seg030:00F5 ,
ES:BX.
seg030:00F2 16- , .
- .
7

Read-only memory
100%
9
Enhanced Graphics Adapter
10
Video Graphics Array
8

233

7.2. QR9: 7.
80286 , -.
80386 , MS-DOS ,
DOS-: ,
CPU API ,
MS-DOS. DOS/4GW ( DOOM ),
Phar Lap, PMODE
, 16- Windows 3.x, Win32.

7.2

QR9:

.

, 11 .
, IDA:
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541004
.text:00541008
.text:00541009
.text:0054100D
.text:0054100F
.text:00541013
.text:00541015
.text:00541017
.text:00541019
.text:00541020
.text:00541022
.text:00541029
.text:0054102A
.text:0054102B
.text:0054102B
.text:0054102B
.text:0054102B
.text:0054102D
.text:00541034
.text:00541036
.text:00541038
.text:0054103F
.text:00541040
.text:00541040
.text:00541040
.text:00541040
.text:00541041
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541054
.text:00541058
.text:0054105F
.text:00541063
11

set_bit

proc near

arg_0
arg_4
arg_8
arg_C

=
=
=
=

; CODE XREF: rotate1+42


; rotate2+42 ...

dword ptr 4
dword ptr 8
dword ptr 0Ch
byte ptr 10h

mov
al, [esp+arg_C]
mov
ecx, [esp+arg_8]
push
esi
mov
esi, [esp+4+arg_0]
test
al, al
mov
eax, [esp+4+arg_4]
mov
dl, 1
jz
short loc_54102B
shl
dl, cl
mov
cl, cube64[eax+esi*8]
or
cl, dl
mov
cube64[eax+esi*8], cl
pop
esi
retn
; --------------------------------------------------------------------------loc_54102B:

set_bit

shl
mov
not
and
mov
pop
retn
endp

; CODE XREF: set_bit+15


dl, cl
cl, cube64[eax+esi*8]
dl
cl, dl
cube64[eax+esi*8], cl
esi

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

get_bit

proc near

arg_0
arg_4
arg_8

= dword ptr 4
= dword ptr 8
= byte ptr 0Ch
mov
mov
mov
mov
shr

; CODE XREF: rotate1+16


; rotate2+16 ...

eax, [esp+arg_4]
ecx, [esp+arg_0]
al, cube64[eax+ecx*8]
cl, [esp+arg_8]
al, cl

234

7.2. QR9: 7.
.text:00541065
.text:00541067
.text:00541067
.text:00541067
.text:00541067
.text:00541068
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541070
.text:00541073
.text:00541074
.text:00541075
.text:00541079
.text:0054107A
.text:0054107B
.text:0054107D
.text:00541081
.text:00541081
.text:00541081
.text:00541083
.text:00541083
.text:00541083
.text:00541084
.text:00541085
.text:00541086
.text:0054108B
.text:0054108E
.text:00541091
.text:00541092
.text:00541095
.text:00541097
.text:00541098
.text:0054109B
.text:0054109E
.text:005410A0
.text:005410A4
.text:005410A9
.text:005410A9
.text:005410A9
.text:005410AB
.text:005410AB
.text:005410AB
.text:005410AE
.text:005410AF
.text:005410B0
.text:005410B1
.text:005410B2
.text:005410B7
.text:005410BA
.text:005410BB
.text:005410BE
.text:005410C0
.text:005410C1
.text:005410C4
.text:005410C7
.text:005410C9
.text:005410CA
.text:005410CB
.text:005410CC
.text:005410CD
.text:005410D0
.text:005410D0
.text:005410D0
.text:005410D0
.text:005410D1
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E0

get_bit

and
retn
endp

al, 1

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

rotate1

proc near

; CODE XREF: rotate_all_with_password+8E

internal_array_64= byte ptr -40h


arg_0
= dword ptr 4
sub
push
push
mov
push
push
xor
lea

esp,
ebx
ebp
ebp,
esi
edi
edi,
ebx,

40h

[esp+48h+arg_0]

edi
; EDI is loop1 counter
[esp+50h+internal_array_64]

first_loop1_begin:
xor

esi, esi

first_loop2_begin:
push
push
push
call
add
mov
inc
cmp
jl
inc
add
cmp
jl
lea
mov

; CODE XREF: rotate1+25


ebp
; arg_0
esi
edi
get_bit
esp, 0Ch
[ebx+esi], al
; store to internal array
esi
esi, 8
short first_loop2_begin
edi
ebx, 8
edi, 8
short first_loop1_begin
ebx, [esp+50h+internal_array_64]
edi, 7
; EDI is loop1 counter, initial state is 7

second_loop1_begin:
xor

esi, esi

second_loop2_begin:
mov
push
push
push
push
call
add
inc
cmp
jl
dec
add
cmp
jg
pop
pop
pop
pop
add
retn
rotate1
endp

; CODE XREF: rotate1+2E


; ESI is loop2 counter

; CODE XREF: rotate1+57


; ESI is loop2 counter

; CODE XREF: rotate1+4E


al, [ebx+esi]
; value from internal array
eax
ebp
; arg_0
edi
esi
set_bit
esp, 10h
esi
; increment loop2 counter
esi, 8
short second_loop2_begin
edi
; decrement loop2 counter
ebx, 8
edi, 0FFFFFFFFh
short second_loop1_begin
edi
esi
ebp
ebx
esp, 40h

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

235

7.2. QR9: 7.
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E3
.text:005410E4
.text:005410E5
.text:005410E9
.text:005410EA
.text:005410EB
.text:005410ED
.text:005410F1
.text:005410F1
.text:005410F1
.text:005410F3
.text:005410F3
.text:005410F3
.text:005410F4
.text:005410F5
.text:005410F6
.text:005410FB
.text:005410FE
.text:00541101
.text:00541102
.text:00541105
.text:00541107
.text:00541108
.text:0054110B
.text:0054110E
.text:00541110
.text:00541114
.text:00541119
.text:00541119
.text:00541119
.text:0054111B
.text:0054111B
.text:0054111B
.text:0054111E
.text:0054111F
.text:00541120
.text:00541121
.text:00541122
.text:00541127
.text:0054112A
.text:0054112B
.text:0054112E
.text:00541130
.text:00541131
.text:00541134
.text:00541137
.text:00541139
.text:0054113A
.text:0054113B
.text:0054113C
.text:0054113D
.text:00541140
.text:00541140
.text:00541140
.text:00541140
.text:00541141
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541150
.text:00541153
.text:00541154
.text:00541155
.text:00541159

rotate2

proc near

; CODE XREF: rotate_all_with_password+7A

internal_array_64= byte ptr -40h


arg_0
= dword ptr 4
sub
push
push
mov
push
push
xor
lea

esp,
ebx
ebp
ebp,
esi
edi
edi,
ebx,

40h

xor

esi, esi

push
push
push
call
add
mov
inc
cmp
jl
inc
add
cmp
jl
lea
mov

; CODE XREF: rotate2+25


esi
; loop2
edi
; loop1
ebp
; arg_0
get_bit
esp, 0Ch
[ebx+esi], al
; store to internal array
esi
; increment loop1 counter
esi, 8
short loc_5410F3
edi
; increment loop2 counter
ebx, 8
edi, 8
short loc_5410F1
ebx, [esp+50h+internal_array_64]
edi, 7
; loop1 counter is initial state 7

xor

esi, esi

[esp+48h+arg_0]

edi
; loop1 counter
[esp+50h+internal_array_64]

loc_5410F1:

loc_5410F3:

loc_541119:

loc_54111B:

rotate2

mov
push
push
push
push
call
add
inc
cmp
jl
dec
add
cmp
jg
pop
pop
pop
pop
add
retn
endp

; CODE XREF: rotate2+2E


; loop2 counter

; CODE XREF: rotate2+57


; loop2 counter

;
al, [ebx+esi]
;
eax
edi
;
esi
;
ebp
;
set_bit
esp, 10h
esi
;
esi, 8
short loc_54111B
edi
;
ebx, 8
edi, 0FFFFFFFFh
short loc_541119
edi
esi
ebp
ebx
esp, 40h

CODE XREF: rotate2+4E


get byte from internal array
loop1 counter
loop2 counter
arg_0

increment loop2 counter

decrement loop2 counter

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

rotate3

proc near

var_40
arg_0

= byte ptr -40h


= dword ptr 4
sub
push
push
mov
push

; CODE XREF: rotate_all_with_password+66

esp, 40h
ebx
ebp
ebp, [esp+48h+arg_0]
esi

236

7.2. QR9: 7.
.text:0054115A
.text:0054115B
.text:0054115D
.text:00541161
.text:00541161
.text:00541161
.text:00541163
.text:00541163
.text:00541163
.text:00541164
.text:00541165
.text:00541166
.text:0054116B
.text:0054116E
.text:00541171
.text:00541172
.text:00541175
.text:00541177
.text:00541178
.text:0054117B
.text:0054117E
.text:00541180
.text:00541182
.text:00541186
.text:00541186
.text:00541186
.text:0054118B
.text:0054118B
.text:0054118B
.text:0054118D
.text:0054118E
.text:0054118F
.text:00541190
.text:00541191
.text:00541196
.text:00541199
.text:0054119A
.text:0054119B
.text:0054119E
.text:005411A0
.text:005411A1
.text:005411A4
.text:005411A6
.text:005411A7
.text:005411A8
.text:005411A9
.text:005411AA
.text:005411AD
.text:005411AD
.text:005411AD
.text:005411AD
.text:005411AE
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B0
.text:005411B4
.text:005411B5
.text:005411B7
.text:005411BA
.text:005411C0
.text:005411C1
.text:005411C5
.text:005411C6
.text:005411C7
.text:005411C7
.text:005411C7
.text:005411CB
.text:005411CC

push
xor
lea

edi
edi, edi
ebx, [esp+50h+var_40]

xor

esi, esi

push
push
push
call
add
mov
inc
cmp
jl
inc
add
cmp
jl
xor
lea

; CODE XREF: rotate3+25


esi
ebp
edi
get_bit
esp, 0Ch
[ebx+esi], al
esi
esi, 8
short loc_541163
edi
ebx, 8
edi, 8
short loc_541161
ebx, ebx
edi, [esp+50h+var_40]

mov

esi, 7

mov
push
push
push
push
call
add
inc
dec
cmp
jg
inc
cmp
jl
pop
pop
pop
pop
add
retn
endp

al, [edi]
eax
ebx
ebp
esi
set_bit
esp, 10h
edi
esi
esi, 0FFFFFFFFh
short loc_54118B
ebx
ebx, 8
short loc_541186
edi
esi
ebp
ebx
esp, 40h

loc_541161:

; CODE XREF: rotate3+2E

loc_541163:

loc_541186:

; CODE XREF: rotate3+54

loc_54118B:

rotate3

; CODE XREF: rotate3+4E

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

rotate_all_with_password proc near

arg_0
arg_4

; CODE XREF: crypt+1F


; decrypt+36

= dword ptr
= dword ptr

4
8

mov
push
mov
cmp
jz
push
mov
push
push

eax,
ebp
ebp,
byte
exit
ebx
ebx,
esi
edi

[esp+arg_0]

movsx
push
call

; CODE XREF: rotate_all_with_password+9F


eax, byte ptr [ebp+0]
eax
; C
_tolower

loop_begin:

eax
ptr [eax], 0

[esp+8+arg_4]

237

7.2. QR9: 7.
.text:005411D1
.text:005411D4
.text:005411D6
.text:005411D8
.text:005411DA
.text:005411DC
.text:005411DF
.text:005411E2
.text:005411E5
.text:005411E7
.text:005411EA
.text:005411EA
.text:005411EA
.text:005411EF
.text:005411F1
.text:005411F3
.text:005411F6
.text:005411F8
.text:005411FA
.text:005411FC
.text:00541201
.text:00541202
.text:00541204
.text:00541207
.text:00541209
.text:0054120A
.text:0054120C
.text:0054120D
.text:0054120F
.text:00541211
.text:00541213
.text:00541215
.text:00541215
.text:00541215
.text:00541216
.text:0054121B
.text:0054121E
.text:0054121F
.text:00541221
.text:00541223
.text:00541223
.text:00541223
.text:00541223
.text:00541225
.text:00541227
.text:00541229
.text:00541229
.text:00541229
.text:0054122A
.text:0054122F
.text:00541232
.text:00541233
.text:00541235
.text:00541237
.text:00541237
.text:00541237
.text:00541237
.text:00541239
.text:0054123B
.text:0054123D
.text:0054123D
.text:0054123D
.text:0054123E
.text:00541243
.text:00541246
.text:00541247
.text:00541249
.text:00541249
.text:00541249
.text:00541249
.text:0054124C
.text:0054124D
.text:0054124F
.text:00541255
.text:00541256
.text:00541257

add
cmp
jl
cmp
jg
movsx
sub
cmp
jle
sub
skip_subtracting:
mov
imul
mov
shr
add
mov
mov
mov
cdq
idiv
sub
jz
dec
jz
dec
jnz
test
jle
mov

esp, 4
al, a
short next_character_in_password
al, z
short next_character_in_password
ecx, al
ecx, a
ecx, 24
short skip_subtracting
ecx, 24
; CODE XREF: rotate_all_with_password+35
eax,
ecx
eax,
eax,
edx,
eax,
esi,
ecx,

55555556h
edx
1Fh
eax
ecx
edx
3

ecx
edx, 0
short call_rotate1
edx
short call_rotate2
edx
short next_character_in_password
ebx, ebx
short next_character_in_password
edi, ebx

call_rotate3:

; CODE XREF: rotate_all_with_password+6F


push
esi
call
rotate3
add
esp, 4
dec
edi
jnz
short call_rotate3
jmp
short next_character_in_password
; --------------------------------------------------------------------------call_rotate2:
test
jle
mov

; CODE XREF: rotate_all_with_password+5A


ebx, ebx
short next_character_in_password
edi, ebx

loc_541229:

; CODE XREF: rotate_all_with_password+83


push
esi
call
rotate2
add
esp, 4
dec
edi
jnz
short loc_541229
jmp
short next_character_in_password
; --------------------------------------------------------------------------call_rotate1:
test
jle
mov

; CODE XREF: rotate_all_with_password+57


ebx, ebx
short next_character_in_password
edi, ebx

push
call
add
dec
jnz

esi
rotate1
esp, 4
edi
short loc_54123D

loc_54123D:

; CODE XREF: rotate_all_with_password+97

next_character_in_password:
mov
inc
test
jnz
pop
pop
pop

; CODE XREF: rotate_all_with_password+26


; rotate_all_with_password+2A ...

al, [ebp+1]
ebp
al, al
loop_begin
edi
esi
ebx

238

7.2. QR9: 7.
.text:00541258
.text:00541258
.text:00541258
.text:00541259
.text:00541259
.text:00541259
.text:00541259
.text:0054125A
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541261
.text:00541265
.text:00541266
.text:00541267
.text:00541268
.text:0054126A
.text:0054126A
.text:0054126A
.text:0054126E
.text:00541273
.text:00541275
.text:0054127A
.text:0054127C
.text:0054127D
.text:0054127F
.text:00541284
.text:00541288
.text:0054128A
.text:0054128D
.text:00541290
.text:00541295
.text:0054129A
.text:0054129D
.text:0054129F
.text:005412A1
.text:005412A3
.text:005412A4
.text:005412A5
.text:005412A6
.text:005412A7
.text:005412A7
.text:005412A7
.text:005412A7
.text:005412A8
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B0
.text:005412B4
.text:005412B5
.text:005412B6
.text:005412B7
.text:005412B8
.text:005412B9
.text:005412BE
.text:005412BF
.text:005412C3
.text:005412C8
.text:005412CC

exit:

; CODE XREF: rotate_all_with_password+A

pop
ebp
retn
rotate_all_with_password endp
; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

crypt

proc near

arg_0
arg_4
arg_8

= dword ptr
= dword ptr
= dword ptr
push
mov
push
push
push
xor

loc_54126A:

crypt

; CODE XREF: crypt_file+8A


4
8
0Ch

ebx
ebx, [esp+4+arg_0]
ebp
esi
edi
ebp, ebp

; CODE XREF: crypt+41


mov
eax, [esp+10h+arg_8]
mov
ecx, 10h
mov
esi, ebx
mov
edi, offset cube64
push
1
push
eax
rep movsd
call
rotate_all_with_password
mov
eax, [esp+18h+arg_4]
mov
edi, ebx
add
ebp, 40h
add
esp, 8
mov
ecx, 10h
mov
esi, offset cube64
add
ebx, 40h
cmp
ebp, eax
rep movsd
jl
short loc_54126A
pop
edi
pop
esi
pop
ebp
pop
ebx
retn
endp

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

; int __cdecl decrypt(int, int, void *Src)


decrypt
proc near
; CODE XREF: decrypt_file+99
arg_0
arg_4
Src

= dword ptr
= dword ptr
= dword ptr
mov
push
push
push
push
push
call
push
mov
call
mov
add

4
8
0Ch

eax, [esp+Src]
ebx
ebp
esi
edi
eax
; Src
__strdup
eax
; Str
[esp+18h+Src], eax
__strrev
ebx, [esp+18h+arg_0]
esp, 8

239

7.2. QR9: 7.
.text:005412CF
.text:005412D1
.text:005412D1
.text:005412D1
.text:005412D6
.text:005412D8
.text:005412DD
.text:005412DF
.text:005412E1
.text:005412E5
.text:005412E6
.text:005412EB
.text:005412EF
.text:005412F1
.text:005412F4
.text:005412F7
.text:005412FC
.text:00541301
.text:00541304
.text:00541306
.text:00541308
.text:0054130A
.text:0054130E
.text:0054130F
.text:00541314
.text:00541317
.text:00541318
.text:00541319
.text:0054131A
.text:0054131B
.text:0054131B
.text:0054131B
.text:0054131B
.text:0054131C
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541324
.text:00541325
.text:0054132A
.text:0054132B
.text:00541330
.text:00541332
.text:00541335
.text:00541337
.text:00541339
.text:0054133E
.text:00541343
.text:00541346
.text:00541347
.text:00541348
.text:00541348
.text:00541348
.text:00541348
.text:00541349
.text:0054134A
.text:0054134B
.text:0054134D
.text:0054134F
.text:00541350
.text:00541355
.text:00541356
.text:0054135B
.text:0054135D
.text:0054135F
.text:00541360
.text:00541364

xor
loc_5412D1:

decrypt

ebp, ebp

; CODE XREF: decrypt+58


mov
ecx, 10h
mov
esi, ebx
mov
edi, offset cube64
push
3
rep movsd
mov
ecx, [esp+14h+Src]
push
ecx
call
rotate_all_with_password
mov
eax, [esp+18h+arg_4]
mov
edi, ebx
add
ebp, 40h
add
esp, 8
mov
ecx, 10h
mov
esi, offset cube64
add
ebx, 40h
cmp
ebp, eax
rep movsd
jl
short loc_5412D1
mov
edx, [esp+10h+Src]
push
edx
; Memory
call
_free
add
esp, 4
pop
edi
pop
esi
pop
ebp
pop
ebx
retn
endp

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

; int __cdecl crypt_file(int Str, char *Filename, int password)


crypt_file
proc near
; CODE XREF: _main+42
Str
Filename
password

= dword ptr
= dword ptr
= dword ptr

4
8
0Ch

mov
eax, [esp+Str]
push
ebp
push
offset Mode
; "rb"
push
eax
; Filename
call
_fopen
; open file
mov
ebp, eax
add
esp, 8
test
ebp, ebp
jnz
short loc_541348
push
offset Format
; "Cannot open input file!\n"
call
_printf
add
esp, 4
pop
ebp
retn
; --------------------------------------------------------------------------loc_541348:
push
push
push
push
push
push
call
push
call
push
push
push
mov
call

; CODE XREF: crypt_file+17


ebx
esi
edi
2
; Origin
0
; Offset
ebp
; File
_fseek
ebp
; File
_ftell
; get file size
0
; Origin
0
; Offset
ebp
; File
[esp+2Ch+Str], eax
_fseek
; rewind to start

240

7.2. QR9: 7.
.text:00541369
.text:0054136D
.text:00541370
.text:00541373
.text:00541374
.text:00541379
.text:0054137B
.text:0054137D
.text:0054137F
.text:00541381
.text:00541383
.text:00541384
.text:00541387
.text:00541389
.text:0054138B
.text:0054138D
.text:00541390
.text:00541392
.text:00541396
.text:00541397
.text:00541398
.text:0054139D
.text:0054139E
.text:005413A3
.text:005413A7
.text:005413A8
.text:005413A9
.text:005413AA
.text:005413AF
.text:005413B3
.text:005413B6
.text:005413BB
.text:005413BC
.text:005413C1
.text:005413C3
.text:005413C4
.text:005413C6
.text:005413C8
.text:005413CD
.text:005413D2
.text:005413D3
.text:005413D5
.text:005413D9
.text:005413DB
.text:005413DC
.text:005413E1
.text:005413E2
.text:005413E4
.text:005413E5
.text:005413E6
.text:005413EB
.text:005413EC
.text:005413F1
.text:005413F2
.text:005413F7
.text:005413FA
.text:005413FB
.text:005413FC
.text:005413FD
.text:005413FE
.text:005413FE
.text:005413FE
.text:005413FE
.text:005413FF
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400

crypt_file

mov
esi, [esp+2Ch+Str]
and
esi, 0FFFFFFC0h ; reset all lowest 6 bits
add
esi, 40h
; align size to 64-byte border
push
esi
; Size
call
_malloc
mov
ecx, esi
mov
ebx, eax
; allocated buffer pointer -> to EBX
mov
edx, ecx
xor
eax, eax
mov
edi, ebx
push
ebp
; File
shr
ecx, 2
rep stosd
mov
ecx, edx
push
1
; Count
and
ecx, 3
rep stosb
; memset (buffer, 0, aligned_size)
mov
eax, [esp+38h+Str]
push
eax
; ElementSize
push
ebx
; DstBuf
call
_fread
; read file
push
ebp
; File
call
_fclose
mov
ecx, [esp+44h+password]
push
ecx
; password
push
esi
; aligned size
push
ebx
; buffer
call
crypt
; do crypt
mov
edx, [esp+50h+Filename]
add
esp, 40h
push
offset aWb
; "wb"
push
edx
; Filename
call
_fopen
mov
edi, eax
push
edi
; File
push
1
; Count
push
3
; Size
push
offset aQr9
; "QR9"
call
_fwrite
; write file signature
push
edi
; File
push
1
; Count
lea
eax, [esp+30h+Str]
push
4
; Size
push
eax
; Str
call
_fwrite
; write original file size
push
edi
; File
push
1
; Count
push
esi
; Size
push
ebx
; Str
call
_fwrite
; write crypted file
push
edi
; File
call
_fclose
push
ebx
; Memory
call
_free
add
esp, 40h
pop
edi
pop
esi
pop
ebx
pop
ebp
retn
endp

; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================

; int __cdecl decrypt_file(char *Filename, int, void *Src)


decrypt_file
proc near
; CODE XREF: _main+6E
Filename
arg_4
Src

= dword ptr
= dword ptr
= dword ptr
mov

4
8
0Ch

eax, [esp+Filename]

241

7.2. QR9: 7.
.text:00541404
.text:00541405
.text:00541406
.text:00541407
.text:00541408
.text:0054140D
.text:0054140E
.text:00541413
.text:00541415
.text:00541418
.text:0054141A
.text:0054141C
.text:00541421
.text:00541426
.text:00541429
.text:0054142A
.text:0054142B
.text:0054142C
.text:0054142D
.text:0054142E
.text:0054142E
.text:0054142E
.text:0054142E
.text:00541430
.text:00541432
.text:00541433
.text:00541438
.text:00541439
.text:0054143E
.text:00541440
.text:00541442
.text:00541443
.text:00541445
.text:0054144A
.text:0054144B
.text:00541450
.text:00541451
.text:00541453
.text:00541455
.text:00541456
.text:00541457
.text:0054145C
.text:0054145D
.text:00541462
.text:00541465
.text:0054146A
.text:0054146F
.text:00541471
.text:00541473
.text:00541475
.text:00541477
.text:0054147C
.text:00541481
.text:00541484
.text:00541485
.text:00541486
.text:00541487
.text:00541488
.text:00541489
.text:00541489
.text:00541489
.text:00541489
.text:0054148D
.text:00541490
.text:00541493
.text:00541496
.text:00541497
.text:00541498
.text:00541499
.text:0054149E
.text:005414A2
.text:005414A7
.text:005414A8
.text:005414AD
.text:005414AF
.text:005414B0

push
ebx
push
ebp
push
esi
push
edi
push
offset aRb
; "rb"
push
eax
; Filename
call
_fopen
mov
esi, eax
add
esp, 8
test
esi, esi
jnz
short loc_54142E
push
offset aCannotOpenIn_0 ; "Cannot open input file!\n"
call
_printf
add
esp, 4
pop
edi
pop
esi
pop
ebp
pop
ebx
retn
; --------------------------------------------------------------------------loc_54142E:

; CODE XREF: decrypt_file+1A


push
2
; Origin
push
0
; Offset
push
esi
; File
call
_fseek
push
esi
; File
call
_ftell
push
0
; Origin
push
0
; Offset
push
esi
; File
mov
ebp, eax
call
_fseek
push
ebp
; Size
call
_malloc
push
esi
; File
mov
ebx, eax
push
1
; Count
push
ebp
; ElementSize
push
ebx
; DstBuf
call
_fread
push
esi
; File
call
_fclose
add
esp, 34h
mov
ecx, 3
mov
edi, offset aQr9_0 ; "QR9"
mov
esi, ebx
xor
edx, edx
repe cmpsb
jz
short loc_541489
push
offset aFileIsNotCrypt ; "File is not crypted!\n"
call
_printf
add
esp, 4
pop
edi
pop
esi
pop
ebp
pop
ebx
retn
; --------------------------------------------------------------------------loc_541489:
mov
mov
add
lea
push
push
push
call
mov
push
push
call
mov
push
push

; CODE XREF: decrypt_file+75


eax, [esp+10h+Src]
edi, [ebx+3]
ebp, 0FFFFFFF9h
esi, [ebx+7]
eax
; Src
ebp
; int
esi
; int
decrypt
ecx, [esp+1Ch+arg_4]
offset aWb_0
; "wb"
ecx
; Filename
_fopen
ebp, eax
ebp
; File
1
; Count

242

7.2. QR9: 7.
.text:005414B2
.text:005414B3
.text:005414B4
.text:005414B9
.text:005414BA
.text:005414BF
.text:005414C0
.text:005414C5
.text:005414C8
.text:005414C9
.text:005414CA
.text:005414CB
.text:005414CC
.text:005414CC decrypt_file

push
push
call
push
call
push
call
add
pop
pop
pop
pop
retn
endp

edi
esi
_fwrite
ebp
_fclose
ebx
_free
esp, 2Ch
edi
esi
ebp
ebx

; Size
; Str
; File
; Memory

.
. , .
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320
.text:00541320

; int __cdecl crypt_file(int Str, char *Filename, int password)


crypt_file
proc near
Str
Filename
password

= dword ptr
= dword ptr
= dword ptr

4
8
0Ch

:
.text:00541320
mov
eax, [esp+Str]
.text:00541324
push
ebp
.text:00541325
push
offset Mode
; "rb"
.text:0054132A
push
eax
; Filename
.text:0054132B
call
_fopen
; open file
.text:00541330
mov
ebp, eax
.text:00541332
add
esp, 8
.text:00541335
test
ebp, ebp
.text:00541337
jnz
short loc_541348
.text:00541339
push
offset Format
; "Cannot open input file!\n"
.text:0054133E
call
_printf
.text:00541343
add
esp, 4
.text:00541346
pop
ebp
.text:00541347
retn
.text:00541348 ; --------------------------------------------------------------------------.text:00541348
.text:00541348 loc_541348:

fseek()/ftell():
.text:00541348
.text:00541349
.text:0054134A
.text:0054134B
.text:0054134D
.text:0054134F

push
push
push
push
push
push

ebx
esi
edi
2
0
ebp

; Origin
; Offset
; File

;
.text:00541350 call
_fseek
.text:00541355 push
ebp
; File
.text:00541356 call
_ftell
;
.text:0054135B push
0
; Origin
.text:0054135D push
0
; Offset
.text:0054135F push
ebp
; File
.text:00541360 mov
[esp+2Ch+Str], eax
;
.text:00541364 call
_fseek

64- .
64 . :
64, , 1, 64.
64 64. .
.text:00541369 mov

esi, [esp+2Ch+Str]

; 6

243

7.2. QR9: 7.
.text:0054136D and

esi, 0FFFFFFC0h

; 64-
.text:00541370 add
esi, 40h

:
.text:00541373
.text:00541374

push
call

esi
_malloc

; Size

memset(), .., 12 .
.text:00541379
.text:0054137B
.text:0054137D
.text:0054137F
.text:00541381
.text:00541383
.text:00541384
.text:00541387
.text:00541389
.text:0054138B
.text:0054138D
.text:00541390

mov
ecx,
mov
ebx,
mov
edx,
xor
eax,
mov
edi,
push
ebp
shr
ecx,
rep stosd
mov
ecx,
push
1
and
ecx,
rep stosb

esi
eax
ecx
eax
ebx

; -> to EBX

; File
2
edx
; Count
3
; memset (buffer, 0, _)

fread().
.text:00541392
.text:00541396
.text:00541397
.text:00541398
.text:0054139D
.text:0054139E

mov
push
push
call
push
call

eax, [esp+38h+Str]
eax
; ElementSize
ebx
; DstBuf
_fread
; read file
ebp
; File
_fclose

crypt(). , () .
.text:005413A3
.text:005413A7
.text:005413A8
.text:005413A9
.text:005413AA

mov
push
push
push
call

ecx, [esp+44h+password]
ecx
; password
esi
; aligned size
ebx
; buffer
crypt
; do crypt

. , , ! , , .
.text:005413AF
.text:005413B3
.text:005413B6
.text:005413BB
.text:005413BC
.text:005413C1

mov
add
push
push
call
mov

edx, [esp+50h+Filename]
esp, 40h
offset aWb
; "wb"
edx
; Filename
_fopen
edi, eax

EDI. QR9.
.text:005413C3
.text:005413C4
.text:005413C6
.text:005413C8
.text:005413CD

push
push
push
push
call

edi
1
3
offset aQr9
_fwrite

;
;
;
;
;

File
Count
Size
"QR9"
write file signature

( ):
.text:005413D2
.text:005413D3
.text:005413D5
.text:005413D9
.text:005413DB
.text:005413DC

push
push
lea
push
push
call

edi
; File
1
; Count
eax, [esp+30h+Str]
4
; Size
eax
; Str
_fwrite
; write original file size

:
12

malloc() + memset() calloc()

244

7.2. QR9: 7.
.text:005413E1
.text:005413E2
.text:005413E4
.text:005413E5
.text:005413E6

push
push
push
push
call

edi
1
esi
ebx
_fwrite

;
;
;
;
;

File
Count
Size
Str
write crypted file

:
.text:005413EB
.text:005413EC
.text:005413F1
.text:005413F2
.text:005413F7
.text:005413FA
.text:005413FB
.text:005413FC
.text:005413FD
.text:005413FE
.text:005413FE crypt_file

push
call
push
call
add
pop
pop
pop
pop
retn
endp

edi
_fclose
ebx
_free
esp, 40h
edi
esi
ebx
ebp

; File
; Memory

:
void crypt_file(char *fin, char* fout, char *pw)
{
FILE *f;
int flen, flen_aligned;
BYTE *buf;
f=fopen(fin, "rb");
if (f==NULL)
{
printf ("Cannot open input file!\n");
return;
};
fseek (f, 0, SEEK_END);
flen=ftell (f);
fseek (f, 0, SEEK_SET);
flen_aligned=(flen&0xFFFFFFC0)+0x40;
buf=(BYTE*)malloc (flen_aligned);
memset (buf, 0, flen_aligned);
fread (buf, flen, 1, f);
fclose (f);
crypt (buf, flen_aligned, pw);
f=fopen(fout, "wb");
fwrite ("QR9", 3, 1, f);
fwrite (&flen, 4, 1, f);
fwrite (buf, flen_aligned, 1, f);
fclose (f);
free (buf);
};

:
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541400
.text:00541404
.text:00541405
.text:00541406
.text:00541407

; int __cdecl decrypt_file(char *Filename, int, void *Src)


decrypt_file
proc near
Filename
arg_4
Src

= dword ptr
= dword ptr
= dword ptr
mov
push
push
push
push

4
8
0Ch

eax, [esp+Filename]
ebx
ebp
esi
edi

245

7.2. QR9: 7.
.text:00541408
push
offset aRb
; "rb"
.text:0054140D
push
eax
; Filename
.text:0054140E
call
_fopen
.text:00541413
mov
esi, eax
.text:00541415
add
esp, 8
.text:00541418
test
esi, esi
.text:0054141A
jnz
short loc_54142E
.text:0054141C
push
offset aCannotOpenIn_0 ; "Cannot open input file!\n"
.text:00541421
call
_printf
.text:00541426
add
esp, 4
.text:00541429
pop
edi
.text:0054142A
pop
esi
.text:0054142B
pop
ebp
.text:0054142C
pop
ebx
.text:0054142D
retn
.text:0054142E ; --------------------------------------------------------------------------.text:0054142E
.text:0054142E loc_54142E:
.text:0054142E
push
2
; Origin
.text:00541430
push
0
; Offset
.text:00541432
push
esi
; File
.text:00541433
call
_fseek
.text:00541438
push
esi
; File
.text:00541439
call
_ftell
.text:0054143E
push
0
; Origin
.text:00541440
push
0
; Offset
.text:00541442
push
esi
; File
.text:00541443
mov
ebp, eax
.text:00541445
call
_fseek
.text:0054144A
push
ebp
; Size
.text:0054144B
call
_malloc
.text:00541450
push
esi
; File
.text:00541451
mov
ebx, eax
.text:00541453
push
1
; Count
.text:00541455
push
ebp
; ElementSize
.text:00541456
push
ebx
; DstBuf
.text:00541457
call
_fread
.text:0054145C
push
esi
; File
.text:0054145D
call
_fclose

( 3 ):
.text:00541462
.text:00541465
.text:0054146A
.text:0054146F
.text:00541471
.text:00541473
.text:00541475

add
esp, 34h
mov
ecx, 3
mov
edi, offset aQr9_0 ; "QR9"
mov
esi, ebx
xor
edx, edx
repe cmpsb
jz
short loc_541489

:
.text:00541477
push
offset aFileIsNotCrypt ; "File is not crypted!\n"
.text:0054147C
call
_printf
.text:00541481
add
esp, 4
.text:00541484
pop
edi
.text:00541485
pop
esi
.text:00541486
pop
ebp
.text:00541487
pop
ebx
.text:00541488
retn
.text:00541489 ; --------------------------------------------------------------------------.text:00541489
.text:00541489 loc_541489:

decrypt().
.text:00541489
.text:0054148D
.text:00541490
.text:00541493
.text:00541496
.text:00541497
.text:00541498
.text:00541499
.text:0054149E
.text:005414A2

mov
mov
add
lea
push
push
push
call
mov
push

eax, [esp+10h+Src]
edi, [ebx+3]
ebp, 0FFFFFFF9h
esi, [ebx+7]
eax
; Src
ebp
; int
esi
; int
decrypt
ecx, [esp+1Ch+arg_4]
offset aWb_0
; "wb"

246

7.2. QR9: 7.
.text:005414A7
.text:005414A8
.text:005414AD
.text:005414AF
.text:005414B0
.text:005414B2
.text:005414B3
.text:005414B4
.text:005414B9
.text:005414BA
.text:005414BF
.text:005414C0
.text:005414C5
.text:005414C8
.text:005414C9
.text:005414CA
.text:005414CB
.text:005414CC
.text:005414CC decrypt_file

push
call
mov
push
push
push
push
call
push
call
push
call
add
pop
pop
pop
pop
retn
endp

ecx
_fopen
ebp, eax
ebp
1
edi
esi
_fwrite
ebp
_fclose
ebx
_free
esp, 2Ch
edi
esi
ebp
ebx

; Filename

;
;
;
;

File
Count
Size
Str

; File
; Memory

:
void decrypt_file(char *fin, char* fout, char *pw)
{
FILE *f;
int real_flen, flen;
BYTE *buf;
f=fopen(fin, "rb");
if (f==NULL)
{
printf ("Cannot open input file!\n");
return;
};
fseek (f, 0, SEEK_END);
flen=ftell (f);
fseek (f, 0, SEEK_SET);
buf=(BYTE*)malloc (flen);
fread (buf, flen, 1, f);
fclose (f);
if (memcmp (buf, "QR9", 3)!=0)
{
printf ("File is not crypted!\n");
return;
};
memcpy (&real_flen, buf+3, 4);
decrypt (buf+(3+4), flen-(3+4), pw);
f=fopen(fout, "wb");
fwrite (buf+(3+4), real_flen, 1, f);
fclose (f);
free (buf);
};

OK, .
crypt():
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541260
.text:00541261

crypt

proc near

arg_0
arg_4
arg_8

= dword ptr
= dword ptr
= dword ptr
push
mov

4
8
0Ch

ebx
ebx, [esp+4+arg_0]

247

7.2. QR9: 7.
.text:00541265
.text:00541266
.text:00541267
.text:00541268
.text:0054126A
.text:0054126A loc_54126A:

push
push
push
xor

ebp
esi
edi
ebp, ebp

,
cube64. ECX. MOVSD 32- , , 16 32-
64 .
.text:0054126A
.text:0054126E
.text:00541273
.text:00541275
.text:0054127A
.text:0054127C
.text:0054127D

mov
eax,
mov
ecx,
mov
esi,
mov
edi,
push
1
push
eax
rep movsd

[esp+10h+arg_8]
10h
ebx
; EBX is pointer within input buffer
offset cube64

rotate_all_with_password():
.text:0054127F

call

rotate_all_with_password

cube64 :
.text:00541284
.text:00541288
.text:0054128A
.text:0054128D
.text:00541290
.text:00541295
.text:0054129A
.text:0054129D
.text:0054129F

mov
eax,
mov
edi,
add
ebp,
add
esp,
mov
ecx,
mov
esi,
add
ebx,
cmp
ebp,
rep movsd

[esp+18h+arg_4]
ebx
40h
8
10h
offset cube64
40h ; add 64 to input buffer pointer
eax ; EBP contain ammount of crypted data.

EBP , .
.text:005412A1
.text:005412A3
.text:005412A4
.text:005412A5
.text:005412A6
.text:005412A7
.text:005412A7 crypt

jl
pop
pop
pop
pop
retn
endp

short loc_54126A
edi
esi
ebp
ebx

crypt():
void crypt (BYTE *buf, int sz, char *pw)
{
int i=0;
do
{
memcpy (cube, buf+i, 8*8);
rotate_all (pw, 1);
memcpy (buf+i, cube, 8*8);
i+=64;
}
while (i<sz);
};

OK, rotate_all_with_password(). :
. crypt(), 1 decrypt() ( rotate_all_with_password()
), 3.
.text:005411B0 rotate_all_with_password proc near
.text:005411B0
.text:005411B0 arg_0
= dword ptr 4
.text:005411B0 arg_4
= dword ptr 8
.text:005411B0
.text:005411B0
mov
eax, [esp+arg_0]
.text:005411B4
push
ebp
.text:005411B5
mov
ebp, eax

248

7.2. QR9: 7.
. , :
.text:005411B7
.text:005411BA
.text:005411C0
.text:005411C1
.text:005411C5
.text:005411C6
.text:005411C7
.text:005411C7 loop_begin:

cmp
jz
push
mov
push
push

byte ptr [eax], 0


exit
ebx
ebx, [esp+8+arg_4]
esi
edi

tolower(), .
.text:005411C7
.text:005411CB
.text:005411CC
.text:005411D1

movsx
push
call
add

eax, byte ptr [ebp+0]


eax
; C
_tolower
esp, 4

, , ! ,
, ,
.
.text:005411D4
.text:005411D6
.text:005411D8
.text:005411DA
.text:005411DC

cmp
jl
cmp
jg
movsx

al, a
short next_character_in_password
al, z
short next_character_in_password
ecx, al

a (97) .
.text:005411DF

sub

ecx, a

; 97

, 0 a, 1 b, . 25 z.
.text:005411E2
.text:005411E5
.text:005411E7

cmp
jle
sub

ecx, 24
short skip_subtracting
ecx, 24

, y z . , y 0, z
1. 26 0..23, ( 24).
.text:005411EA
.text:005411EA skip_subtracting:

; CODE XREF: rotate_all_with_password+35

, , . 9 (1.12).
, , 3.
.text:005411EA
.text:005411EF
.text:005411F1
.text:005411F3
.text:005411F6
.text:005411F8
.text:005411FA
.text:005411FC
.text:00541201
.text:00541202

mov
imul
mov
shr
add
mov
mov
mov
cdq
idiv

eax,
ecx
eax,
eax,
edx,
eax,
esi,
ecx,

55555556h
edx
1Fh
eax
ecx
edx
3

ecx

EDX .
.text:00541204
.text:00541207
.text:00541209
.text:0054120A
.text:0054120C
.text:0054120D
.text:0054120F
.text:00541211
.text:00541213

sub
jz
dec
jz
dec
jnz
test
jle
mov

edx, 0
short call_rotate1 ; 0, rotate1
edx
short call_rotate2 ; .. 1, rotate2
edx
short next_character_in_password
ebx, ebx
short next_character_in_password
edi, ebx

2, rotate3(). EDX rotate_all_with_password().


, 1 , 3 . , rotate1/2/3
, .
249

7.2. QR9: 7.
.text:00541215
.text:00541215
.text:00541216
.text:0054121B
.text:0054121E
.text:0054121F
.text:00541221
.text:00541223
.text:00541223
.text:00541223
.text:00541225
.text:00541227
.text:00541229
.text:00541229
.text:00541229
.text:0054122A
.text:0054122F
.text:00541232
.text:00541233
.text:00541235
.text:00541237
.text:00541237
.text:00541237
.text:00541239
.text:0054123B
.text:0054123D
.text:0054123D
.text:0054123D
.text:0054123E
.text:00541243
.text:00541246
.text:00541247
.text:00541249

call_rotate3:
push
call
add
dec
jnz
jmp

esi
rotate3
esp, 4
edi
short call_rotate3
short next_character_in_password

test
jle
mov

ebx, ebx
short next_character_in_password
edi, ebx

push
call
add
dec
jnz
jmp

esi
rotate2
esp, 4
edi
short loc_541229
short next_character_in_password

test
jle
mov

ebx, ebx
short next_character_in_password
edi, ebx

push
call
add
dec
jnz

esi
rotate1
esp, 4
edi
short loc_54123D

call_rotate2:

loc_541229:

call_rotate1:

loc_54123D:

.
.text:00541249 next_character_in_password:
.text:00541249
mov
al, [ebp+1]

:
.text:0054124C
inc
ebp
.text:0054124D
test
al, al
.text:0054124F
jnz
loop_begin
.text:00541255
pop
edi
.text:00541256
pop
esi
.text:00541257
pop
ebx
.text:00541258
.text:00541258 exit:
.text:00541258
pop
ebp
.text:00541259
retn
.text:00541259 rotate_all_with_password endp

:
void rotate_all (char *pwd, int v)
{
char *p=pwd;
while (*p)
{
char c=*p;
int q;
c=tolower (c);
if (c>=a && c<=z)
{
q=c-a;
if (q>24)
q-=24;
int quotient=q/3;
int remainder=q % 3;
switch (remainder)

250

7.2. QR9: 7.
{
case 0: for (int i=0; i<v; i++) rotate1 (quotient); break;
case 1: for (int i=0; i<v; i++) rotate2 (quotient); break;
case 2: for (int i=0; i<v; i++) rotate3 (quotient); break;
};
};
p++;
};
};

rotate1/2/3. .
set_bit() get_bit().
get_bit():
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541050
.text:00541054
.text:00541058
.text:0054105F
.text:00541063
.text:00541065
.text:00541067
.text:00541067

get_bit

proc near

arg_0
arg_4
arg_8

= dword ptr 4
= dword ptr 8
= byte ptr 0Ch

get_bit

mov
mov
mov
mov
shr
and
retn
endp

eax, [esp+arg_4]
ecx, [esp+arg_0]
al, cube64[eax+ecx*8]
cl, [esp+arg_8]
al, cl
al, 1

. . . : cube64: arg_4 + arg_0 * 8.


arg_8.
, set_bit():
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541000
.text:00541004
.text:00541008
.text:00541009
.text:0054100D
.text:0054100F
.text:00541013
.text:00541015

set_bit

proc near

arg_0
arg_4
arg_8
arg_C

=
=
=
=

dword ptr 4
dword ptr 8
dword ptr 0Ch
byte ptr 10h

mov
mov
push
mov
test
mov
mov
jz

al, [esp+arg_C]
ecx, [esp+arg_8]
esi
esi, [esp+4+arg_0]
al, al
eax, [esp+4+arg_4]
dl, 1
short loc_54102B

DL 1. arg_8. , arg_8
4, DL 0x10 1000 .
.text:00541017
.text:00541019

shl
mov

dl, cl
cl, cube64[eax+esi*8]

.
.text:00541020

or

cl, dl

:
.text:00541022
mov
cube64[eax+esi*8], cl
.text:00541029
pop
esi
.text:0054102A
retn
.text:0054102B ; --------------------------------------------------------------------------.text:0054102B
.text:0054102B loc_54102B:
.text:0054102B
shl
dl, cl

arg_C . . .
.text:0054102D

mov

cl, cube64[eax+esi*8]

251

7.2. QR9: 7.
. . . DL. , DL 0x10 1000 ,
0xEF NOT 11101111 .
.text:00541034

not

dl

, , CL
DL DL, . DL, , 11101111 ,
( ).
.text:00541036

and

cl, dl

mov
pop
retn
endp

cube64[eax+esi*8], cl
esi


.text:00541038
.text:0054103F
.text:00541040
.text:00541040 set_bit

get_bit() arg_C ,
, , , 1.
64. set_bit() get_bit()
. , 8*8.
, :
#define IS_SET(flag, bit)
#define SET_BIT(var, bit)
#define REMOVE_BIT(var, bit)

((flag) & (bit))


((var) |= (bit))
((var) &= ~(bit))

char cube[8][8];
void set_bit (int x, int y, int shift, int bit)
{
if (bit)
SET_BIT (cube[x][y], 1<<shift);
else
REMOVE_BIT (cube[x][y], 1<<shift);
};
int get_bit (int x, int y, int shift)
{
if ((cube[x][y]>>shift)&1==1)
return 1;
return 0;
};

rotate1/2/3.
.text:00541070 rotate1
.text:00541070

proc near

64 :
.text:00541070 internal_array_64= byte ptr -40h
.text:00541070 arg_0
= dword ptr 4
.text:00541070
.text:00541070
sub
esp, 40h
.text:00541073
push
ebx
.text:00541074
push
ebp
.text:00541075
mov
ebp, [esp+48h+arg_0]
.text:00541079
push
esi
.text:0054107A
push
edi
.text:0054107B
xor
edi, edi
; EDI is loop1 counter

EBX
.text:0054107D
.text:00541081

lea

ebx, [esp+50h+internal_array_64]

:
.text:00541081 first_loop1_begin:
.text:00541081
xor
esi, esi
.text:00541083

; ESI is

252

7.2. QR9: 7.
.text:00541083 first_loop2_begin:
.text:00541083
push
ebp
; arg_0
.text:00541084
push
esi
;
.text:00541085
push
edi
;
.text:00541086
call
get_bit
.text:0054108B
add
esp, 0Ch
.text:0054108E
mov
[ebx+esi], al
;
.text:00541091
inc
esi
;
.text:00541092
cmp
esi, 8
.text:00541095
jl
short first_loop2_begin
.text:00541097
inc
edi
;
; 8
.text:00541098
add
ebx, 8
.text:0054109B
cmp
edi, 8
.text:0054109E
jl
short first_loop1_begin

0..7. ,
get_bit(). get_bit() rotate1(). get_bit() .
:
.text:005410A0
lea
ebx, [esp+50h+internal_array_64]
.text:005410A4
mov
edi, 7
; EDI , - 7
.text:005410A9
.text:005410A9 second_loop1_begin:
.text:005410A9
xor
esi, esi
; ESI -
.text:005410AB
.text:005410AB second_loop2_begin:
.text:005410AB
mov
al, [ebx+esi]
;
.text:005410AE
push
eax
.text:005410AF
push
ebp
; arg_0
.text:005410B0
push
edi
;
.text:005410B1
push
esi
;
.text:005410B2
call
set_bit
.text:005410B7
add
esp, 10h
.text:005410BA
inc
esi
;
.text:005410BB
cmp
esi, 8
.text:005410BE
jl
short second_loop2_begin
.text:005410C0
dec
edi
;
.text:005410C1
add
ebx, 8
;
.text:005410C4
cmp
edi, 0FFFFFFFFh
.text:005410C7
jg
short second_loop1_begin
.text:005410C9
pop
edi
.text:005410CA
pop
esi
.text:005410CB
pop
ebp
.text:005410CC
pop
ebx
.text:005410CD
add
esp, 40h
.text:005410D0
retn
.text:005410D0 rotate1
endp

. . . cube set_bit(), , ! 7 0,
1 !
:
void rotate1 (int v)
{
bool tmp[8][8]; // internal array
int i, j;
for (i=0; i<8; i++)
for (j=0; j<8; j++)
tmp[i][j]=get_bit (i, j, v);
for (i=0; i<8; i++)
for (j=0; j<8; j++)
set_bit (j, 7-i, v, tmp[x][y]);
};

, rotate2():
.text:005410E0 rotate2 proc near
.text:005410E0

253

7.2. QR9: 7.
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E0
.text:005410E3
.text:005410E4
.text:005410E5
.text:005410E9
.text:005410EA
.text:005410EB
.text:005410ED
.text:005410F1
.text:005410F1
.text:005410F1
.text:005410F3
.text:005410F3
.text:005410F3
.text:005410F4
.text:005410F5
.text:005410F6
.text:005410FB
.text:005410FE
.text:00541101
.text:00541102
.text:00541105
.text:00541107
.text:00541108
.text:0054110B
.text:0054110E
.text:00541110
.text:00541114
.text:00541119
.text:00541119
.text:00541119
.text:0054111B
.text:0054111B
.text:0054111B
.text:0054111E
.text:0054111F
.text:00541120
.text:00541121
.text:00541122
.text:00541127
.text:0054112A
.text:0054112B
.text:0054112E
.text:00541130
.text:00541131
.text:00541134
.text:00541137
.text:00541139
.text:0054113A
.text:0054113B
.text:0054113C
.text:0054113D
.text:00541140
.text:00541140

internal_array_64 = byte ptr -40h


arg_0 = dword ptr 4
sub
push
push
mov
push
push
xor
lea

esp,
ebx
ebp
ebp,
esi
edi
edi,
ebx,

40h

[esp+48h+arg_0]

edi
;
[esp+50h+internal_array_64]

loc_5410F1:
xor
esi, esi
loc_5410F3:
push
push
push
call
add
mov
inc
cmp
jl
inc
add
cmp
jl
lea
mov

esi
;
edi
;
ebp
; arg_0
get_bit
esp, 0Ch
[ebx+esi], al
;
esi
;
esi, 8
short loc_5410F3
edi
;
ebx, 8
edi, 8
short loc_5410F1
ebx, [esp+50h+internal_array_64]
edi, 7
; - 7

loc_541119:
xor
esi, esi

loc_54111B:
mov
al, [ebx+esi]
;
push
eax
push
edi
;
push
esi
;
push
ebp
;
call
set_bit
add
esp, 10h
inc
esi
;
cmp
esi, 8
jl
short loc_54111B
dec
edi
;
add
ebx, 8
cmp
edi, 0FFFFFFFFh
jg
short loc_541119
pop
edi
pop
esi
pop
ebp
pop
ebx
add
esp, 40h
retn
rotate2 endp




arg_0

, get_bit() set_bit(). - :
void rotate2 (int v)
{
bool tmp[8][8]; // internal array
int i, j;
for (i=0; i<8; i++)
for (j=0; j<8; j++)
tmp[i][j]=get_bit (v, i, j);
for (i=0; i<8; i++)
for (j=0; j<8; j++)
set_bit (v, j, 7-i, tmp[i][j]);
};

rotate3():
254

7.2. QR9: 7.
void rotate3 (int v)
{
bool tmp[8][8];
int i, j;
for (i=0; i<8; i++)
for (j=0; j<8; j++)
tmp[i][j]=get_bit (i, v, j);
for (i=0; i<8; i++)
for (j=0; j<8; j++)
set_bit (7-j, v, i, tmp[i][j]);
};

. cube64 8*8*8, ,
get_bit() set_bit() .
rotate1/2/3 . ,
v 0..7
, 8*8*8?!
, .
decrypt(), :
void decrypt (BYTE *buf, int sz, char *pw)
{
char *p=strdup (pw);
strrev (p);
int i=0;
do
{
memcpy (cube, buf+i, 8*8);
rotate_all (p, 3);
memcpy (buf+i, cube, 8*8);
i+=64;
}
while (i<sz);
free (p);
};

crypt(), strrev()
rotate_all() 3.
, , rotate1/2/3 .
! ,
! ,
.
rotate1(), , . rotate2(), , . rotate3(), , .
rotate_all()
q=c-a;
if (q>24)
q-=24;
int quotient=q/3; // in range 0..7
int remainder=q % 3;
switch (remainder)
{
case 0: for (int i=0; i<v; i++) rotate1 (quotient); break; // front
case 1: for (int i=0; i<v; i++) rotate2 (quotient); break; // top
case 2: for (int i=0; i<v; i++) rotate3 (quotient); break; // left
};

: ( ) ( ). 3*8 = 24,
24- .

255

7.2. QR9: 7.
: , , .
:
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#define IS_SET(flag, bit)
#define SET_BIT(var, bit)
#define REMOVE_BIT(var, bit)

((flag) & (bit))


((var) |= (bit))
((var) &= ~(bit))

static BYTE cube[8][8];


void set_bit (int x, int y, int z, bool bit)
{
if (bit)
SET_BIT (cube[x][y], 1<<z);
else
REMOVE_BIT (cube[x][y], 1<<z);
};
bool get_bit (int x, int y, int z)
{
if ((cube[x][y]>>z)&1==1)
return true;
return false;
};
void rotate_f (int row)
{
bool tmp[8][8];
int x, y;
for (x=0; x<8; x++)
for (y=0; y<8; y++)
tmp[x][y]=get_bit (x, y, row);
for (x=0; x<8; x++)
for (y=0; y<8; y++)
set_bit (y, 7-x, row, tmp[x][y]);
};
void rotate_t (int row)
{
bool tmp[8][8];
int y, z;
for (y=0; y<8; y++)
for (z=0; z<8; z++)
tmp[y][z]=get_bit (row, y, z);
for (y=0; y<8; y++)
for (z=0; z<8; z++)
set_bit (row, z, 7-y, tmp[y][z]);
};
void rotate_l (int row)
{
bool tmp[8][8];
int x, z;
for (x=0; x<8; x++)
for (z=0; z<8; z++)
tmp[x][z]=get_bit (x, row, z);
for (x=0; x<8; x++)
for (z=0; z<8; z++)
set_bit (7-z, row, x, tmp[x][z]);
};
void rotate_all (char *pwd, int v)
{
char *p=pwd;

256

7.2. QR9: 7.
while (*p)
{
char c=*p;
int q;
c=tolower (c);
if (c>=a && c<=z)
{
q=c-a;
if (q>24)
q-=24;
int quotient=q/3;
int remainder=q % 3;
switch (remainder)
{
case 0: for (int i=0; i<v; i++) rotate1 (quotient); break;
case 1: for (int i=0; i<v; i++) rotate2 (quotient); break;
case 2: for (int i=0; i<v; i++) rotate3 (quotient); break;
};
};
p++;
};
};
void crypt (BYTE *buf, int sz, char *pw)
{
int i=0;
do
{
memcpy (cube, buf+i, 8*8);
rotate_all (pw, 1);
memcpy (buf+i, cube, 8*8);
i+=64;
}
while (i<sz);
};
void decrypt (BYTE *buf, int sz, char *pw)
{
char *p=strdup (pw);
strrev (p);
int i=0;
do
{
memcpy (cube, buf+i, 8*8);
rotate_all (p, 3);
memcpy (buf+i, cube, 8*8);
i+=64;
}
while (i<sz);
free (p);
};
void crypt_file(char *fin, char* fout, char *pw)
{
FILE *f;
int flen, flen_aligned;
BYTE *buf;
f=fopen(fin, "rb");
if (f==NULL)
{
printf ("Cannot open input file!\n");
return;
};
fseek (f, 0, SEEK_END);
flen=ftell (f);

257

7.2. QR9: 7.
fseek (f, 0, SEEK_SET);
flen_aligned=(flen&0xFFFFFFC0)+0x40;
buf=(BYTE*)malloc (flen_aligned);
memset (buf, 0, flen_aligned);
fread (buf, flen, 1, f);
fclose (f);
crypt (buf, flen_aligned, pw);
f=fopen(fout, "wb");
fwrite ("QR9", 3, 1, f);
fwrite (&flen, 4, 1, f);
fwrite (buf, flen_aligned, 1, f);
fclose (f);
free (buf);
};
void decrypt_file(char *fin, char* fout, char *pw)
{
FILE *f;
int real_flen, flen;
BYTE *buf;
f=fopen(fin, "rb");
if (f==NULL)
{
printf ("Cannot open input file!\n");
return;
};
fseek (f, 0, SEEK_END);
flen=ftell (f);
fseek (f, 0, SEEK_SET);
buf=(BYTE*)malloc (flen);
fread (buf, flen, 1, f);
fclose (f);
if (memcmp (buf, "QR9", 3)!=0)
{
printf ("File is not crypted!\n");
return;
};
memcpy (&real_flen, buf+3, 4);
decrypt (buf+(3+4), flen-(3+4), pw);
f=fopen(fout, "wb");
fwrite (buf+(3+4), real_flen, 1, f);
fclose (f);
free (buf);
};
// run: input output 0/1 password
// 0 for encrypt, 1 for decrypt
int main(int argc, char *argv[])
{
if (argc!=5)
{
printf ("Incorrect parameters!\n");

258

7.3. SAP

7.
return 1;
};
if (strcmp (argv[3], "0")==0)
crypt_file (argv[1], argv[2], argv[4]);
else
if (strcmp (argv[3], "1")==0)
decrypt_file (argv[1], argv[2], argv[4]);
else
printf ("Wrong param %s\n", argv[3]);
return 0;

};

7.3
7.3.1

SAP
SAP

( TDW_NOCOMPRESS SAPGUI13 .)
SAPGUI SAP (
).
TDW_NOCOMPRESS 1,
.
, :

. 7.1:

, - .
, . : TDW_NOCOMPRES
- SAPGUI. : data compression switched off
- . FAR
SAPguilib.dll.
SAPguilib.dll IDA TDW_NOCOMPRESS. ,
.
13

GUI- SAP

259

7.3. SAP
7.
( SAPGUI 720 win32, SAPguilib.dll 7200,1,0,9009):
.text:6440D51B
.text:6440D51E
.text:6440D51F
.text:6440D524
.text:6440D528
.text:6440D52D
.text:6440D52E
.text:6440D52F
.text:6440D534

lea
push
push
mov
call
pop
pop
push
lea

eax, [ebp+2108h+var_211C]
eax
; int
offset aTdw_nocompress ; "TDW_NOCOMPRESS"
byte ptr [edi+15h], 0
chk_env
ecx
ecx
offset byte_64443AF8
ecx, [ebp+2108h+var_211C]

; demangled name: int ATL::CStringT::Compare(char const *)const


.text:6440D537
call
ds:mfc90_1603
.text:6440D53D
test
eax, eax
.text:6440D53F
jz
short loc_6440D55A
.text:6440D541
lea
ecx, [ebp+2108h+var_211C]
; demangled name: const char* ATL::CSimpleStringT::operator PCXSTR
.text:6440D544
call
ds:mfc90_910
.text:6440D54A
push
eax
; Str
.text:6440D54B
call
ds:atoi
.text:6440D551
test
eax, eax
.text:6440D553
setnz
al
.text:6440D556
pop
ecx
.text:6440D557
mov
[edi+15h], al

chk_env() ,
MFC, atoi()14 . , edi+15h.
chk_env ( ):
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F20
.text:64413F21
.text:64413F23
.text:64413F26
.text:64413F2D
.text:64413F34
.text:64413F39

; int __cdecl chk_env(char *VarName, int)


chk_env
proc near
DstSize
var_8
DstBuf
VarName
arg_4

=
=
=
=
=

dword
dword
dword
dword
dword

push
mov
sub
mov
mov
push
mov

ptr -0Ch
ptr -8
ptr -4
ptr 8
ptr 0Ch
ebp
ebp, esp
esp, 0Ch
[ebp+DstSize], 0
[ebp+DstBuf], 0
offset unk_6444C88C
ecx, [ebp+arg_4]

; (demangled name) ATL::CStringT::operator=(char const *)


.text:64413F3C
call
ds:mfc90_820
.text:64413F42
mov
eax, [ebp+VarName]
.text:64413F45
push
eax
; VarName
.text:64413F46
mov
ecx, [ebp+DstSize]
.text:64413F49
push
ecx
; DstSize
.text:64413F4A
mov
edx, [ebp+DstBuf]
.text:64413F4D
push
edx
; DstBuf
.text:64413F4E
lea
eax, [ebp+DstSize]
.text:64413F51
push
eax
; ReturnSize
.text:64413F52
call
ds:getenv_s
.text:64413F58
add
esp, 10h
.text:64413F5B
mov
[ebp+var_8], eax
.text:64413F5E
cmp
[ebp+var_8], 0
.text:64413F62
jz
short loc_64413F68
.text:64413F64
xor
eax, eax
.text:64413F66
jmp
short loc_64413FBC
.text:64413F68 ; --------------------------------------------------------------------------.text:64413F68
.text:64413F68 loc_64413F68:
.text:64413F68
cmp
[ebp+DstSize], 0
.text:64413F6C
jnz
short loc_64413F72
.text:64413F6E
xor
eax, eax
.text:64413F70
jmp
short loc_64413FBC
14

260

7.3. SAP

7.

.text:64413F72 ; --------------------------------------------------------------------------.text:64413F72
.text:64413F72 loc_64413F72:
.text:64413F72
mov
ecx, [ebp+DstSize]
.text:64413F75
push
ecx
.text:64413F76
mov
ecx, [ebp+arg_4]
; demangled name: ATL::CSimpleStringT<char, 1>::Preallocate(int)
.text:64413F79
call
ds:mfc90_2691
.text:64413F7F
mov
[ebp+DstBuf], eax
.text:64413F82
mov
edx, [ebp+VarName]
.text:64413F85
push
edx
; VarName
.text:64413F86
mov
eax, [ebp+DstSize]
.text:64413F89
push
eax
; DstSize
.text:64413F8A
mov
ecx, [ebp+DstBuf]
.text:64413F8D
push
ecx
; DstBuf
.text:64413F8E
lea
edx, [ebp+DstSize]
.text:64413F91
push
edx
; ReturnSize
.text:64413F92
call
ds:getenv_s
.text:64413F98
add
esp, 10h
.text:64413F9B
mov
[ebp+var_8], eax
.text:64413F9E
push
0FFFFFFFFh
.text:64413FA0
mov
ecx, [ebp+arg_4]
; demangled name: ATL::CSimpleStringT::ReleaseBuffer(int)
.text:64413FA3
call
ds:mfc90_5835
.text:64413FA9
cmp
[ebp+var_8], 0
.text:64413FAD
jz
short loc_64413FB3
.text:64413FAF
xor
eax, eax
.text:64413FB1
jmp
short loc_64413FBC
.text:64413FB3 ; --------------------------------------------------------------------------.text:64413FB3
.text:64413FB3 loc_64413FB3:
.text:64413FB3
mov
ecx, [ebp+arg_4]
; demangled name: const char* ATL::CSimpleStringT::operator PCXSTR
.text:64413FB6
call
ds:mfc90_910
.text:64413FBC
.text:64413FBC loc_64413FBC:
.text:64413FBC
.text:64413FBC
mov
esp, ebp
.text:64413FBE
pop
ebp
.text:64413FBF
retn
.text:64413FBF chk_env
endp

. getenv_s()15 getenv()16 MSVC.


MFC.
. SAPGUI -, :
15
16

http://msdn.microsoft.com/en-us/library/tb2sfw2z(VS.80).aspx

261

7.3. SAP
DPTRACE
TDW_HEXDUMP
TDW_WORKDIR
TDW_SPLASHSRCEENOFF
TDW_REPLYTIMEOUT
TDW_PLAYBACKTIMEOUT
TDW_NOCOMPRESS
TDW_EXPERT
TDW_PLAYBACKPROGRESS
TDW_PLAYBACKNETTRAFFIC
TDW_PLAYLOG
TDW_PLAYTIME
TDW_LOGFILE
TDW_WAN
TDW_FULLMENU
SAP_CP / SAP_CODEPAGE
UPDOWNLOAD_CP
SNC_PARTNERNAME
SNC_QOP
SNC_LIB
SAPGUI_INPLACE

7.
GUI-OPTION: Trace set to %d
GUI-OPTION: Hexdump enabled
GUI-OPTION: working directory %s
GUI-OPTION: Splash Screen Off / GUI-OPTION: Splash Screen On
GUI-OPTION: reply timeout %d milliseconds
GUI-OPTION: PlaybackTimeout set to %d milliseconds
GUI-OPTION: no compression read
GUI-OPTION: expert mode
GUI-OPTION: PlaybackProgress
GUI-OPTION: PlaybackNetTraffic
GUI-OPTION: /PlayLog is YES, file %s
GUI-OPTION: /PlayTime set to %d milliseconds
GUI-OPTION: TDW_LOGFILE %s
GUI-OPTION: WAN - low speed connection enabled
GUI-OPTION: FullMenu enabled
GUI-OPTION: SAP_CODEPAGE %d
GUI-OPTION: UPDOWNLOAD_CP %d
GUI-OPTION: SNC name %s
GUI-OPTION: SNC_QOP %s
GUI-OPTION: SNC is set to: %s
GUI-OPTION: environment variable SAPGUI_INPLACE is on

EDI. EDI :
.text:6440EE00
.text:6440EE03
.text:6440EE06
.text:6440EE0B
.text:6440EE0D
.text:6440EE0F
.text:6440EE11
.text:6440EE13
.text:6440EE14
"...
.text:6440EE19
.text:6440EE1F

lea
lea
call
mov
xor
cmp
jz
push
push

edi, [ebp+2884h+var_2884] ; options here like +0x15...


ecx, [esi+24h]
load_command_line
edi, eax
ebx, ebx
edi, ebx
short loc_6440EE42
edi
offset aSapguiStoppedA ; "Sapgui stopped after commandline interp

push
call

dword_644F93E8
FEWTraceError

, data record mode switched on? ,


CDwsGui::PrepareInfoWindow(). /?
- :
.text:64405160
.text:64405166
"...
.text:6440516B
.text:64405171
.text:64405176

push
push

dword ptr [esi+2854h]


offset aCdwsguiPrepare ; "\nCDwsGui::PrepareInfoWindow: sapgui env

push
call
add

dword ptr [esi+2848h]


dbg
esp, 0Ch

push
push

eax
offset aCclientStart_6 ; "CClient::Start: set shortcut user to

push
call
add

dword ptr [edi+4]


dbg
esp, 0Ch

. . . :
.text:6440237A
.text:6440237B
\%"...
.text:64402380
.text:64402383
.text:64402388

.
:
.text:64404F4F CDwsGui__PrepareInfoWindow proc near
.text:64404F4F
.text:64404F4F pvParam
= byte ptr -3Ch
.text:64404F4F var_38
= dword ptr -38h

262

7.3. SAP
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F4F
.text:64404F51
.text:64404F56
.text:64404F5B
.text:64404F5D
.text:64404F5F
.text:64404F62

7.
var_34
rc
cy
h
var_14
var_10
var_4

=
=
=
=
=
=
=

dword ptr -34h


tagRECT ptr -2Ch
dword ptr -1Ch
dword ptr -18h
dword ptr -14h
dword ptr -10h
dword ptr -4

push
mov
call
mov
xor
lea
mov

; demangled name: ATL::CStringT(void)


.text:64404F65
call
.text:64404F6B
mov
.text:64404F6E
lea
.text:64404F74
push
.text:64404F79
mov

30h
eax, offset loc_64438E00
__EH_prolog3
esi, ecx
; ECX is pointer to object
ebx, ebx
ecx, [ebp+var_14]
[ebp+var_10], ebx

ds:mfc90_316
[ebp+var_4], ebx
edi, [esi+2854h]
offset aEnvironmentInf ; "Environment information:\n"
ecx, edi

; demangled name: ATL::CStringT::operator=(char const *)


.text:64404F7B
call
ds:mfc90_820
.text:64404F81
cmp
[esi+38h], ebx
.text:64404F84
mov
ebx, ds:mfc90_2539
.text:64404F8A
jbe
short loc_64404FA9
.text:64404F8C
push
dword ptr [esi+34h]
.text:64404F8F
lea
eax, [ebp+var_14]
.text:64404F92
push
offset aWorkingDirecto ; "working directory: \%s\n"
.text:64404F97
push
eax
; demangled name: ATL::CStringT::Format(char const *,...)
.text:64404F98
call
ebx ; mfc90_2539
.text:64404F9A
add
esp, 0Ch
.text:64404F9D
lea
eax, [ebp+var_14]
.text:64404FA0
push
eax
.text:64404FA1
mov
ecx, edi
; demangled name: ATL::CStringT::operator+=(class ATL::CSimpleStringT<char, 1> const &)
.text:64404FA3
call
ds:mfc90_941
.text:64404FA9
.text:64404FA9 loc_64404FA9:
.text:64404FA9
mov
eax, [esi+38h]
.text:64404FAC
test
eax, eax
.text:64404FAE
jbe
short loc_64404FD3
.text:64404FB0
push
eax
.text:64404FB1
lea
eax, [ebp+var_14]
.text:64404FB4
push
offset aTraceLevelDAct ; "trace level \%d activated\n"
.text:64404FB9
push
eax
; demangled name: ATL::CStringT::Format(char const *,...)
.text:64404FBA
call
ebx ; mfc90_2539
.text:64404FBC
add
esp, 0Ch
.text:64404FBF
lea
eax, [ebp+var_14]
.text:64404FC2
push
eax
.text:64404FC3
mov
ecx, edi
; demangled name: ATL::CStringT::operator+=(class ATL::CSimpleStringT<char, 1> const &)
.text:64404FC5
call
ds:mfc90_941
.text:64404FCB
xor
ebx, ebx
.text:64404FCD
inc
ebx
.text:64404FCE
mov
[ebp+var_10], ebx
.text:64404FD1
jmp
short loc_64404FD6
.text:64404FD3 ; --------------------------------------------------------------------------.text:64404FD3
.text:64404FD3 loc_64404FD3:
.text:64404FD3
xor
ebx, ebx
.text:64404FD5
inc
ebx
.text:64404FD6
.text:64404FD6 loc_64404FD6:
.text:64404FD6
cmp
[esi+38h], ebx
.text:64404FD9
jbe
short loc_64404FF1
.text:64404FDB
cmp
dword ptr [esi+2978h], 0
.text:64404FE2
jz
short loc_64404FF1

263

7.3. SAP
.text:64404FE4
.text:64404FE9

7.
push
mov

offset aHexdumpInTrace ; "hexdump in trace activated\n"


ecx, edi

; demangled name: ATL::CStringT::operator+=(char const *)


.text:64404FEB
call
ds:mfc90_945
.text:64404FF1
.text:64404FF1 loc_64404FF1:
.text:64404FF1
.text:64404FF1
cmp
byte ptr [esi+78h], 0
.text:64404FF5
jz
short loc_64405007
.text:64404FF7
push
offset aLoggingActivat ; "logging activated\n"
.text:64404FFC
mov
ecx, edi
; demangled name: ATL::CStringT::operator+=(char const *)
.text:64404FFE
call
ds:mfc90_945
.text:64405004
mov
[ebp+var_10], ebx
.text:64405007
.text:64405007 loc_64405007:
.text:64405007
cmp
byte ptr [esi+3Dh], 0
.text:6440500B
jz
short bypass
.text:6440500D
push
offset aDataCompressio ; "data compression switched off\n"
.text:64405012
mov
ecx, edi
; demangled name: ATL::CStringT::operator+=(char const *)
.text:64405014
call
ds:mfc90_945
.text:6440501A
mov
[ebp+var_10], ebx
.text:6440501D
.text:6440501D bypass:
.text:6440501D
mov
eax, [esi+20h]
.text:64405020
test
eax, eax
.text:64405022
jz
short loc_6440503A
.text:64405024
cmp
dword ptr [eax+28h], 0
.text:64405028
jz
short loc_6440503A
.text:6440502A
push
offset aDataRecordMode ; "data record mode switched on\n"
.text:6440502F
mov
ecx, edi
; demangled name: ATL::CStringT::operator+=(char const *)
.text:64405031
call
ds:mfc90_945
.text:64405037
mov
[ebp+var_10], ebx
.text:6440503A
.text:6440503A loc_6440503A:
.text:6440503A
.text:6440503A
mov
ecx, edi
.text:6440503C
cmp
[ebp+var_10], ebx
.text:6440503F
jnz
loc_64405142
.text:64405045
push
offset aForMaximumData ; "\nFor maximum data security delete\nthe s
"...
; demangled name: ATL::CStringT::operator+=(char const *)
.text:6440504A
call
ds:mfc90_945
.text:64405050
xor
edi, edi
.text:64405052
push
edi
; fWinIni
.text:64405053
lea
eax, [ebp+pvParam]
.text:64405056
push
eax
; pvParam
.text:64405057
push
edi
; uiParam
.text:64405058
push
30h
; uiAction
.text:6440505A
call
ds:SystemParametersInfoA
.text:64405060
mov
eax, [ebp+var_34]
.text:64405063
cmp
eax, 1600
.text:64405068
jle
short loc_64405072
.text:6440506A
cdq
.text:6440506B
sub
eax, edx
.text:6440506D
sar
eax, 1
.text:6440506F
mov
[ebp+var_34], eax
.text:64405072
.text:64405072 loc_64405072:
.text:64405072
push
edi
; hWnd
.text:64405073
mov
[ebp+cy], 0A0h
.text:6440507A
call
ds:GetDC
.text:64405080
mov
[ebp+var_10], eax
.text:64405083
mov
ebx, 12Ch
.text:64405088
cmp
eax, edi
.text:6440508A
jz
loc_64405113
.text:64405090
push
11h
; i
.text:64405092
call
ds:GetStockObject
.text:64405098
mov
edi, ds:SelectObject

264

7.3. SAP
.text:6440509E
.text:6440509F
.text:644050A2
.text:644050A4
.text:644050A8
.text:644050AC
.text:644050AF
.text:644050B4
.text:644050B7
.text:644050B8
.text:644050BE
.text:644050C1

7.
push
push
call
and
and
mov
push
lea
push
lea
mov
mov

eax
; h
[ebp+var_10]
; hdc
edi ; SelectObject
[ebp+rc.left], 0
[ebp+rc.top], 0
[ebp+h], eax
401h
; format
eax, [ebp+rc]
eax
; lprc
ecx, [esi+2854h]
[ebp+rc.right], ebx
[ebp+rc.bottom], 0B4h

; demangled name: ATL::CSimpleStringT::GetLength(void)


.text:644050C8
call
ds:mfc90_3178
.text:644050CE
push
eax
; cchText
.text:644050CF
lea
ecx, [esi+2854h]
; demangled name: const char* ATL::CSimpleStringT::operator PCXSTR
.text:644050D5
call
ds:mfc90_910
.text:644050DB
push
eax
; lpchText
.text:644050DC
push
[ebp+var_10]
; hdc
.text:644050DF
call
ds:DrawTextA
.text:644050E5
push
4
; nIndex
.text:644050E7
call
ds:GetSystemMetrics
.text:644050ED
mov
ecx, [ebp+rc.bottom]
.text:644050F0
sub
ecx, [ebp+rc.top]
.text:644050F3
cmp
[ebp+h], 0
.text:644050F7
lea
eax, [eax+ecx+28h]
.text:644050FB
mov
[ebp+cy], eax
.text:644050FE
jz
short loc_64405108
.text:64405100
push
[ebp+h]
; h
.text:64405103
push
[ebp+var_10]
; hdc
.text:64405106
call
edi ; SelectObject
.text:64405108
.text:64405108 loc_64405108:
.text:64405108
push
[ebp+var_10]
; hDC
.text:6440510B
push
0
; hWnd
.text:6440510D
call
ds:ReleaseDC
.text:64405113
.text:64405113 loc_64405113:
.text:64405113
mov
eax, [ebp+var_38]
.text:64405116
push
80h
; uFlags
.text:6440511B
push
[ebp+cy]
; cy
.text:6440511E
inc
eax
.text:6440511F
push
ebx
; cx
.text:64405120
push
eax
; Y
.text:64405121
mov
eax, [ebp+var_34]
.text:64405124
add
eax, 0FFFFFED4h
.text:64405129
cdq
.text:6440512A
sub
eax, edx
.text:6440512C
sar
eax, 1
.text:6440512E
push
eax
; X
.text:6440512F
push
0
; hWndInsertAfter
.text:64405131
push
dword ptr [esi+285Ch] ; hWnd
.text:64405137
call
ds:SetWindowPos
.text:6440513D
xor
ebx, ebx
.text:6440513F
inc
ebx
.text:64405140
jmp
short loc_6440514D
.text:64405142 ; --------------------------------------------------------------------------.text:64405142
.text:64405142 loc_64405142:
.text:64405142
push
offset byte_64443AF8
; demangled name: ATL::CStringT::operator=(char const *)
.text:64405147
call
ds:mfc90_820
.text:6440514D
.text:6440514D loc_6440514D:
.text:6440514D
cmp
dword_6450B970, ebx
.text:64405153
jl
short loc_64405188
.text:64405155
call
sub_6441C910
.text:6440515A
mov
dword_644F858C, ebx
.text:64405160
push
dword ptr [esi+2854h]
.text:64405166
push
offset aCdwsguiPrepare ; "\nCDwsGui::PrepareInfoWindow: sapgui env
"...
.text:6440516B
push
dword ptr [esi+2848h]

265

7.3. SAP
.text:64405171
.text:64405176
.text:64405179
.text:64405183
.text:64405188
.text:64405188 loc_64405188:
.text:64405188
.text:6440518C

7.
call
add
mov
call

dbg
esp, 0Ch
dword_644F858C, 2
sub_6441C920

or
lea

[ebp+var_4], 0FFFFFFFFh
ecx, [ebp+var_14]

; demangled name: ATL::CStringT::~CStringT()


.text:6440518F
call
ds:mfc90_601
.text:64405195
call
__EH_epilog3
.text:6440519A
retn
.text:6440519A CDwsGui__PrepareInfoWindow endp

ECX ( thiscall (2.1.1)).


, , , CDwsGui. ,
.
this+0x3D , :
.text:64405007 loc_64405007:
.text:64405007
.text:6440500B
.text:6440500D
.text:64405012

cmp
jz
push
mov

byte ptr [esi+3Dh], 0


short bypass
offset aDataCompressio ; "data compression switched off\n"
ecx, edi

; demangled name: ATL::CStringT::operator+=(char const *)


.text:64405014
call
ds:mfc90_945
.text:6440501A
mov
[ebp+var_10], ebx
.text:6440501D
.text:6440501D bypass:

, , var_10 , :
.text:6440503C
.text:6440503F

cmp
jnz

[ebp+var_10], ebx
exit ; bypass drawing

; "For maximum data security delete" / "the setting(s) as soon as possible !":
.text:64405045
"...
.text:6440504A
.text:64405050
.text:64405052
.text:64405053
.text:64405056
.text:64405057
.text:64405058
.text:6440505A
.text:64405060
.text:64405063
.text:64405068
.text:6440506A
.text:6440506B
.text:6440506D
.text:6440506F
.text:64405072
.text:64405072 loc_64405072:

push

offset aForMaximumData ; "\nFor maximum data security delete\nthe s

call
xor
push
lea
push
push
push
call
mov
cmp
jle
cdq
sub
sar
mov

ds:mfc90_945 ; ATL::CStringT::operator+=(char const *)


edi, edi
edi
; fWinIni
eax, [ebp+pvParam]
eax
; pvParam
edi
; uiParam
30h
; uiAction
ds:SystemParametersInfoA
eax, [ebp+var_34]
eax, 1600
short loc_64405072

push
mov
call

edi
[ebp+cy], 0A0h
ds:GetDC

eax, edx
eax, 1
[ebp+var_34], eax

:
.text:64405072
.text:64405073
.text:6440507A

; hWnd

.
JNZ . . .
.text:6440503F

jnz

exit ;

. . . JMP SAPGUI !
0x15 load_command_line() (
) this+0x3D CDwsGui::PrepareInfoWindow.
?
266

7.3. SAP
7.
0x15.
SAPGUI, . :
.text:64404C19 sub_64404C19
.text:64404C19
.text:64404C19 arg_0
.text:64404C19
.text:64404C19
.text:64404C1A
.text:64404C1B
.text:64404C1C
.text:64404C1D
.text:64404C21
.text:64404C23
.text:64404C25
.text:64404C27
.text:64404C2A
.text:64404C2D
.text:64404C30
.text:64404C33
.text:64404C36
.text:64404C37
; demangled name:
.text:64404C3A
.text:64404C40
.text:64404C43
.text:64404C46
.text:64404C49
.text:64404C4C
.text:64404C4F

proc near
= dword ptr
push
push
push
push
mov
mov
mov
mov
mov
mov
mov
mov
lea
push
lea

ebx
ebp
esi
edi
edi, [esp+10h+arg_0]
eax, [edi]
esi, ecx ; ESI/ECX are pointers to some unknown object.
[esi], eax
eax, [edi+4]
[esi+4], eax
eax, [edi+8]
[esi+8], eax
eax, [edi+0Ch]
eax
ecx, [esi+0Ch]

ATL::CStringT::operator=(class ATL::CStringT ... &)


call
ds:mfc90_817
mov
eax, [edi+10h]
mov
[esi+10h], eax
mov
al, [edi+14h]
mov
[esi+14h], al
mov
al, [edi+15h] ; copy byte from 0x15 offset
mov
[esi+15h], al ; to 0x15 offset in CDwsGui object

CDwsGui::CopyOptions!
.
CDwsGui::Init():
.text:6440B0BF loc_6440B0BF:
.text:6440B0BF
.text:6440B0C2
.text:6440B0C5
.text:6440B0CB
.text:6440B0CE
.text:6440B0CF

mov
push
mov
lea
push
call

eax, [ebp+arg_0]
[ebp+arg_4]
[esi+2844h], eax
eax, [esi+28h] ; ESI is pointer to CDwsGui object
eax
CDwsGui__CopyOptions

: load_command_line()
CDwsGui this+0x28. 0x15 + 0x28 0x3D. , ,
.
, 0x3D.
CDwsGui::SapguiRun ( ):
.text:64409D58
.text:64409D5B
.text:64409D61
.text:64409D64
.text:64409D65

cmp
lea
setz
push
push

[esi+3Dh], bl
; ESI is pointer to CDwsGui object
ecx, [esi+2B8h]
al
eax
; arg_10 of CConnectionContext::CreateNetwork
dword ptr [esi+64h]

; demangled name: const char* ATL::CSimpleStringT::operator PCXSTR


.text:64409D68
call
ds:mfc90_910
.text:64409D68
; no arguments
.text:64409D6E
push
eax
.text:64409D6F
lea
ecx, [esi+2BCh]
; demangled name: const char* ATL::CSimpleStringT::operator PCXSTR
.text:64409D75
call
ds:mfc90_910
.text:64409D75
; no arguments
.text:64409D7B
push
eax
.text:64409D7C
push
esi
.text:64409D7D
lea
ecx, [esi+8]
.text:64409D80
call
CConnectionContext__CreateNetwork

. setz al xor eax, eax / nop,


TDW_NOCOMPRESS SAPGUI. Wow! ( : ), Wireshark
267

7.3. SAP
7.
! ,
CConnectionContext.
, CConnectionContext::CreateNetwork.
, :
...
.text:64403476
.text:64403479
.text:6440347C
.text:6440347F
.text:64403482
.text:64403485

push
push
push
push
push
call

[ebp+compression]
[ebp+arg_C]
[ebp+arg_8]
[ebp+arg_4]
[ebp+arg_0]
CNetwork__CNetwork

CNetwork::CNetwork.
CNetwork CNetwork
- , , .
.text:64411DF1
.text:64411DF7
.text:64411DF9
.text:64411DFC
.text:64411DFE
.text:64411E00
.text:64411E02
.text:64411E04
.text:64411E04
.text:64411E04
.text:64411E06
.text:64411E07
.text:64411E09
.text:64411E09
.text:64411E09
.text:64411E09
.text:64411E09
.text:64411E0B
.text:64411E0B
.text:64411E0B

cmp
jz
mov
cmp
jz
cmp
jnz

[ebp+compression], esi
short set_EAX_to_0
al, [ebx+78h]
; another value may affect compression?
al, 3
short set_EAX_to_1
al, 4
short set_EAX_to_0

set_EAX_to_1:
xor
eax, eax
inc
eax
; EAX -> 1
jmp
short loc_64411E0B
; --------------------------------------------------------------------------set_EAX_to_0:
xor

eax, eax

; EAX -> 0

mov

[ebx+3A4h], eax ; EBX is pointer to CNetwork object

loc_64411E0B:

CNetwork this+0x3A4.
0x3A4 SAPguilib.dll.
CDwsGui::OnClientMessageWrite ( ):
.text:64406F76 loc_64406F76:
.text:64406F76
.text:64406F79
.text:64406F80
.text:64406F86
.text:64406F8A
.text:64406F8D
.text:64406F8F
.text:64406F91
.text:64406F93
.text:64406F96
.text:64406F99
.text:64406F99 loc_64406F99:
.text:64406F99
.text:64406F9F
.text:64406FA2
.text:64406FA3
.text:64406FA8
.text:64406FAB
.text:64406FAC
.text:64406FAD
.text:64406FAE
.text:64406FB4
.text:64406FB9
.text:64406FBC
.text:64406FBF
.text:64406FC1
.text:64406FC4
.text:64406FCA
.text:64406FCD
.text:64406FCF

mov
cmp
jnz
mov
mov
mov
test
ja
mov
mov

ecx, [ebp+7728h+var_7794]
dword ptr [ecx+3A4h], 1
compression_flag_is_zero
byte ptr [ebx+7], 1
eax, [esi+18h]
ecx, eax
eax, eax
short loc_64406FFF
ecx, [esi+14h]
eax, [esi+20h]

push
lea
push
push
lea
push
push
push
push
call
add
cmp
jz
cmp
jz
cmp
jz
push

dword ptr [edi+2868h] ; int


edx, [ebp+7728h+var_77A4]
edx
; int
30000
; int
edx, [ebp+7728h+Dst]
edx
; Dst
ecx
; int
eax
; Src
dword ptr [edi+28C0h] ; int
sub_644055C5
; actual compression routine
esp, 1Ch
eax, 0FFFFFFF6h
short loc_64407004
eax, 1
loc_6440708C
eax, 2
short loc_64407004
eax

268

7.3. SAP
.text:64406FD0
"...
.text:64406FD5
.text:64406FDA
.text:64406FE0

7.
push

offset aCompressionErr ; "compression error [rc = \%d]- program wi

push
push
call

offset aGui_err_compre ; "GUI_ERR_COMPRESS"


dword ptr [edi+28D0h]
SapPcTxtRead

sub_644055C5. memcpy() -
IDA sub_64417440.
sub_64417440. :
.text:6441747C
.text:64417481
.text:64417483

push
call
add

offset aErrorCsrcompre ; "\nERROR: CsRCompress: invalid handle"


eax ; dword_644F94C8
esp, 4

` . ,
Voila!
SAP - MaxDB. .
:
.text:64406F79
.text:64406F80

cmp
jnz

dword ptr [ecx+3A4h], 1


compression_flag_is_zero

`
JNZ JMP. TDW_NOCOMPRESS. Voila!
Wireshark . , , .
,
.

7.3.2

SAP 6.0

SAP 6.0 IDES


VMware, , , , :
Password logon no longer possible - too many failed attempts, ,
.
SAP disp+work.pdb, : , , , , , . !
TYPEINFODUMP17 PDB- -
grep-.
: + + :
FUNCTION ThVmcSysEvent
Address:
10143190 Size:
675 bytes Index:
60483 TypeIndex:
60484
Type: int NEAR_C ThVmcSysEvent (unsigned int, unsigned char, unsigned short*)
Flags: 0
PARAMETER events
Address: Reg335+288 Size:
4 bytes Index:
60488 TypeIndex:
60489
Type: unsigned int
Flags: d0
PARAMETER opcode
Address: Reg335+296 Size:
1 bytes Index:
60490 TypeIndex:
60491
Type: unsigned char
Flags: d0
PARAMETER serverName
Address: Reg335+304 Size:
8 bytes Index:
60492 TypeIndex:
60493
Type: unsigned short*
Flags: d0
STATIC_LOCAL_VAR func
Address:
12274af0 Size:
8 bytes Index:
60495 TypeIndex:
60496
Type: wchar_t*
Flags: 80
LOCAL_VAR admhead
Address: Reg335+304 Size:
8 bytes Index:
60498 TypeIndex:
60499
Type: unsigned char*
Flags: 90
LOCAL_VAR record
17

http://www.debuginfo.com/tools/typeinfodump.html

269

7.3. SAP

7.

Address: Reg335+64 Size:


Type: AD_RECORD
Flags: 90
LOCAL_VAR adlen
Address: Reg335+296 Size:
Type: int
Flags: 90

204 bytes

4 bytes

Index:

60501

Index:

60508

TypeIndex:

TypeIndex:

60502

60509

:
STRUCT DBSL_STMTID
Size: 120 Variables: 4 Functions: 0 Base classes: 0
MEMBER moduletype
Type: DBSL_MODULETYPE
Offset:
0 Index:
3 TypeIndex:
38653
MEMBER module
Type: wchar_t module[40]
Offset:
4 Index:
3 TypeIndex:
831
MEMBER stmtnum
Type: long
Offset:
84 Index:
3 TypeIndex:
440
MEMBER timestamp
Type: wchar_t timestamp[15]
Offset:
88 Index:
3 TypeIndex:
6612

!
: , , .
ct_level18 , .
disp+work.exe :
cmp
jl
call
lea
mov
call
mov
mov
lea
mov
call
call

cs:ct_level, 1
short loc_1400375DA
DpLock
rcx, aDpxxtool4_c ; "dpxxtool4.c"
edx, 4Eh
; line
CTrcSaveLocation
r8, cs:func_48
rcx, cs:hdl
; hdl
rdx, aSDpreadmemvalu ; "%s: DpReadMemValue (%d)"
r9d, ebx
DpTrcErr
DpUnlock

, - dev_w0, dev_disp dev*.


grep- TYPEINFODUMP:
cat "disp+work.pdb.d" | grep FUNCTION | grep -i password

:
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION

rcui::AgiPassword::DiagISelection
ssf_password_encrypt
ssf_password_decrypt
password_logon_disabled
dySignSkipUserPassword
migrate_password_history
password_is_initial
rcui::AgiPassword::IsVisible
password_distance_ok
get_password_downwards_compatibility
dySignUnSkipUserPassword
rcui::AgiPassword::GetTypeName
rcui::AgiPassword::AgiPassword::1::dtor$2
rcui::AgiPassword::AgiPassword::1::dtor$0
rcui::AgiPassword::AgiPassword::1::dtor$1
usm_set_password
rcui::AgiPassword::TraceTo
days_since_last_password_change
rsecgrp_generate_random_password
rcui::AgiPassword::scalar deleting destructor

18

:
962416a5a613e8e10000000a155369/content.htm

http://help.sap.com/saphelp_nwpi71/helpdata/en/46/

270

7.3. SAP
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION
FUNCTION

7.
password_attempt_limit_exceeded
handle_incorrect_password
rcui::AgiPassword::scalar deleting destructor::1::dtor$1
calculate_new_password_hash
shift_password_to_history
rcui::AgiPassword::GetType
found_password_in_history
rcui::AgiPassword::scalar deleting destructor::1::dtor$0
rcui::AgiObj::IsaPassword
password_idle_check
SlicHwPasswordForDay
rcui::AgiPassword::IsaPassword
rcui::AgiPassword::AgiPassword
delete_user_password
usm_set_user_password
Password_API
get_password_change_for_SSO
password_in_USR40
rsec_agrp_abap_generate_random_password

password locked.
user was locked by subsequently failed password logon attempts
password_attempt_limit_exceeded().
, - : password logon attempt
will be rejected immediately (preventing dictionary attacks), failed-logon lock: expired (but not removed due to
read-only operation), failed-logon lock: expired => removed.
, . chckpass() .
, :
tracer 6.0.1 :
tracer64.exe -a:disp+work.exe bpf=disp+work.exe!chckpass,args:3,unicode
PID=2236|TID=2248|(0) disp+work.exe!chckpass (0x202c770, L"Brewered1
) (called from 0x1402f1060 (disp+work.exe!usrexist+0x3c0))
PID=2236|TID=2248|(0) disp+work.exe!chckpass -> 0x35

", 0x41

: syssigni() -> DyISigni() -> dychkusr() -> usrexist() -> chckpass().


0x35 chckpass() :
.text:00000001402ED567 loc_1402ED567:
.text:00000001402ED567
.text:00000001402ED56A
.text:00000001402ED56F
.text:00000001402ED572
.text:00000001402ED578
.text:00000001402ED57B
.text:00000001402ED581
.text:00000001402ED583
.text:00000001402ED586
.text:00000001402ED58B
.text:00000001402ED58D
.text:00000001402ED58F
.text:00000001402ED594
.text:00000001402ED598
.text:00000001402ED59A
.text:00000001402ED59C
.text:00000001402ED59D
.text:00000001402ED59E
.text:00000001402ED59F

mov
call
cmp
jz
cmp
jz
xor
mov
call
test
jz
mov
add
pop
pop
pop
pop
pop
retn

; CODE XREF: chckpass+B4


rcx, rbx
; usr02
password_idle_check
eax, 33h
loc_1402EDB4E
eax, 36h
loc_1402EDB3D
edx, edx
; usr02_readonly
rcx, rbx
; usr02
password_attempt_limit_exceeded
al, al
short loc_1402ED5A0
eax, 35h
rsp, 60h
r14
r12
rdi
rsi
rbx

, :
tracer64.exe -a:disp+work.exe bpf=disp+work.exe!password_attempt_limit_exceeded,args:4,unicode,rt:0
PID=2744|TID=360|(0) disp+work.exe!password_attempt_limit_exceeded
from 0x1402ed58b (disp+work.exe!chckpass+0xeb))
PID=2744|TID=360|(0) disp+work.exe!password_attempt_limit_exceeded
PID=2744|TID=360|We modify return value (EAX/RAX) of this function
PID=2744|TID=360|(0) disp+work.exe!password_attempt_limit_exceeded
x1402e9794 (disp+work.exe!chngpass+0xe4))

271

(0x202c770, 0, 0x257758, 0) (called


-> 1
to 0
(0x202c770, 0, 0, 0) (called from 0

7.4. ORACLE RDBMS

7.

PID=2744|TID=360|(0) disp+work.exe!password_attempt_limit_exceeded -> 1


PID=2744|TID=360|We modify return value (EAX/RAX) of this function to 0

! .
, , chckpass() ,
:
tracer64.exe -a:disp+work.exe bpf=disp+work.exe!chckpass,args:3,unicode,rt:0
PID=2744|TID=360|(0) disp+work.exe!chckpass (0x202c770, L"bogus
(called from 0x1402f1060 (disp+work.exe!usrexist+0x3c0))
PID=2744|TID=360|(0) disp+work.exe!chckpass -> 0x35
PID=2744|TID=360|We modify return value (EAX/RAX) of this function to 0

", 0x41)

password_attempt_limit_exceeded(),
:
lea
call
test
jz
movzx
cmp
jz
cmp
jz
cmp
jnz

rcx, aLoginFailed_us ; "login/failed_user_auto_unlock"


sapgparam
rax, rax
short loc_1402E19DE
eax, word ptr [rax]
ax, N
short loc_1402E19D4
ax, n
short loc_1402E19D4
ax, 0
short loc_1402E19DE

, sapgparam() - . 1768 . , ,
, .
! , Oracle RDBMS. ,
disp+work ++. , ?

7.4
7.4.1

Oracle RDBMS
V$VERSION Oracle RDBMS

Oracle RDBMS 11.2 , oracle.exe 124


. , Windows 7 x64 (ntoskrnl.exe) 11 ,
Linux 3.9.8 ( ) 31 .
. Oracle RDBMS , SQL*Plus :
SQL> select * from V$VERSION;

:
BANNER
-------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE
11.2.0.1.0
Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

. Oracle RDBMS V$VERSION?


win32-, oracle.exe, .
(.o) Oracle RDBMS Linux,
, oracle.exe win32 .
, V$VERSION kqf.o, Oracle- libserver11.a.
kqfviw, kqf.o:

272

7.4. ORACLE RDBMS

7.
Listing 7.1: kqf.o

.rodata:0800C4A0 kqfviw
.rodata:0800C4A0
.rodata:0800C4A4
.rodata:0800C4A8
.rodata:0800C4AC
.rodata:0800C4B0
.rodata:0800C4B4
.rodata:0800C4B8
.rodata:0800C4BC
.rodata:0800C4C0
.rodata:0800C4C4
.rodata:0800C4C8
.rodata:0800C4CC
.rodata:0800C4D0
.rodata:0800C4D4
.rodata:0800C4D8
.rodata:0800C4DC
.rodata:0800C4E0
.rodata:0800C4E4
.rodata:0800C4E8
.rodata:0800C4EC
.rodata:0800C4F0
.rodata:0800C4F4
.rodata:0800C4F8
.rodata:0800C4FC
.rodata:0800C500
.rodata:0800C504
.rodata:0800C508
.rodata:0800C50C
.rodata:0800C510
.rodata:0800C514
.rodata:0800C518
.rodata:0800C51C
.rodata:0800C520
.rodata:0800C524
.rodata:0800C528
.rodata:0800C52C
.rodata:0800C530
.rodata:0800C534
.rodata:0800C538
.rodata:0800C53C
.rodata:0800C540
.rodata:0800C544
.rodata:0800C548
.rodata:0800C54C
.rodata:0800C550
.rodata:0800C554
.rodata:0800C558
.rodata:0800C55C

dd 0Bh
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd

; DATA XREF: kqfchk:loc_8003A6D


; kqfgbn+34
offset _2__STRING_10102_0 ; "GV$WAITSTAT"
4
offset _2__STRING_10103_0 ; "NULL"
3
0
195h
4
0
0FFFFC1CBh
3
0
0Ah
offset _2__STRING_10104_0 ; "V$WAITSTAT"
4
offset _2__STRING_10103_0 ; "NULL"
3
0
4Eh
3
0
0FFFFC003h
4
0
5
offset _2__STRING_10105_0 ; "GV$BH"
4
offset _2__STRING_10103_0 ; "NULL"
3
0
269h
15h
0
0FFFFC1EDh
8
0
4
offset _2__STRING_10106_0 ; "V$BH"
4
offset _2__STRING_10103_0 ; "NULL"
3
0
0F5h
14h
0
0FFFFC1EEh
5
0

, , Oracle RDBMS, ,
. , Oracle RDBMS
1980-.
: 6 significant initial characters in an external
identifier19
, kqfviw ( ) view V$,
view (fixed views), . ,
kqfviw 12 32- . IDA 12-
. Oracle RDBMS 11.2, 1023
, , 1023 fixed view. ,
.
, .
- view ( ). . .
, fixed views fixed view
V$FIXED_VIEW_DEFINITION (, view kqfviw
19

Draft ANSI C Standard (ANSI X3J11/88-090) (May 13, 1988)

273

7.4. ORACLE RDBMS


kqfvip). , 1023 .

7.

SQL> select * from V$FIXED_VIEW_DEFINITION where view_name=V$VERSION;


VIEW_NAME
-----------------------------VIEW_DEFINITION
-------------------------------------------------------------------------------V$VERSION
select BANNER from GV$VERSION where inst_id = USERENV(Instance)

, V$VERSION thunk view , GV$VERSION, , :


SQL> select * from V$FIXED_VIEW_DEFINITION where view_name=GV$VERSION;
VIEW_NAME
-----------------------------VIEW_DEFINITION
-------------------------------------------------------------------------------GV$VERSION
select inst_id, banner from x$version

X$ Oracle RDBMS , ,
, .
select BANNER from GV$VERSION where inst_id = USERENV(Instance
kqf.o kqfvip:
.
Listing 7.2: kqf.o
rodata:080185A0 kqfvip
.rodata:080185A0
.rodata:080185A0
.rodata:080185A4
.rodata:080185A8
.rodata:080185AC

dd offset _2__STRING_11126_0 ; DATA XREF: kqfgvcn+18


; kqfgvt+F
; "select inst_id,decode(indx,1,data bloc"...
dd offset kqfv459_c_0
dd 0
dd 0

...
.rodata:08019570
"...
.rodata:08019574
.rodata:08019578
.rodata:0801957C
.rodata:08019580
,0"...
.rodata:08019584
.rodata:08019588
.rodata:0801958C
.rodata:08019590
"...
.rodata:08019594

dd offset _2__STRING_11378_0 ; "select

BANNER from GV$VERSION where in

dd
dd
dd
dd

offset kqfv133_c_0
0
0
offset _2__STRING_11379_0 ; "select inst_id,decode(bitand(cfflg,1)

dd
dd
dd
dd

offset kqfv403_c_0
0
0
offset _2__STRING_11380_0 ; "select

STATUS , NAME, IS_RECOVERY_DEST

dd offset kqfv199_c_0

, , 4 . , 1023 . , fixed view. V$VERSION,


, 6 BANNER ( )
0 -:
Listing 7.3: kqf.o
.rodata:080BBAC4 kqfv133_c_0
.rodata:080BBAC8
.rodata:080BBACC
.rodata:080BBAD0

dd
dd
dd
dd

6
; DATA XREF: .rodata:08019574
offset _2__STRING_5017_0 ; "BANNER"
0
offset _2__STRING_0_0

kqfviw kqfvip, SQL-, ,


- fixed view.

274

7.4. ORACLE RDBMS


7.
20
oracle tables ,
Oracle RDBMS Linux. V$VERSION, :
Listing 7.4: oracle tables
kqfviw_element.viewname: [V$VERSION] ?: 0x3 0x43 0x1 0xffffc085 0x4
kqfvip_element.statement: [select BANNER from GV$VERSION where inst_id = USERENV(Instance)]
kqfvip_element.params:
[BANNER]

:
Listing 7.5: oracle tables
kqfviw_element.viewname: [GV$VERSION] ?: 0x3 0x26 0x2 0xffffc192 0x1
kqfvip_element.statement: [select inst_id, banner from x$version]
kqfvip_element.params:
[INST_ID] [BANNER]

Fixed view GV$VERSION V$VERSION , instance. , X$VERSION. X$-,


, , - :
SQL> select * from x$version;
ADDR
INDX
INST_ID
-------- ---------- ---------BANNER
-------------------------------------------------------------------------------0DBAF574
0
1
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
...

ADDR INDX.
kqf.o IDA
X$VERSION, kqftab:
Listing 7.6: kqf.o
.rodata:0803CAC0
.rodata:0803CAC4
.rodata:0803CAC8
.rodata:0803CACC
.rodata:0803CAD0
.rodata:0803CAD4
.rodata:0803CAD8
.rodata:0803CADC
.rodata:0803CAE0
.rodata:0803CAE4
.rodata:0803CAE8
.rodata:0803CAEC
.rodata:0803CAF0
.rodata:0803CAF4
.rodata:0803CAF8
.rodata:0803CAFC
.rodata:0803CB00
.rodata:0803CB04
.rodata:0803CB08
.rodata:0803CB0C
.rodata:0803CB10
.rodata:0803CB14
.rodata:0803CB18
.rodata:0803CB1C

dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd

9
; element number 0x1f6
offset _2__STRING_13113_0 ; "X$VERSION"
4
offset _2__STRING_13114_0 ; "kqvt"
4
4
0
4
0Ch
0FFFFC075h
3
0
7
offset _2__STRING_13115_0 ; "X$KQFSZ"
5
offset _2__STRING_13116_0 ; "kqfsz"
1
38h
0
7
0
0FFFFC09Dh
2
0

X$-, , Oracle RDBMS


. . ,
kqvt. , kq kernel query. v, , version, t
type? , .
kqf.o:
20

http://yurichev.com/oracle_tables.html

275

7.4. ORACLE RDBMS

7.
Listing 7.7: kqf.o

.rodata:0808C360 kqvt_c_0
.rodata:0808C360
.rodata:0808C360
.rodata:0808C384
"
.rodata:0808C3A8
INST_ID"
.rodata:0808C3CC
BANNER"
.rodata:0808C3F0

kqftap_param <4, offset _2__STRING_19_0, 917h, 0, 0, 0, 4, 0, 0>


; DATA XREF: .rodata:08042680
; "ADDR"
kqftap_param <4, offset _2__STRING_20_0, 0B02h, 0, 0, 0, 4, 0, 0> ; "INDX
kqftap_param <7, offset _2__STRING_21_0, 0B02h, 0, 0, 0, 4, 0, 0> ; "
kqftap_param <6, offset _2__STRING_5017_0, 601h, 0, 0, 0, 50h, 0, 0> ; "
kqftap_param <0, offset _2__STRING_0_0, 0, 0, 0, 0, 0, 0, 0>

X$VERSION. kqftap:
Listing 7.8: kqf.o
.rodata:08042680

kqftap_element <0, offset kqvt_c_0, offset kqvrow, 0> ; element 0x1f6

0x1f6 (502-),
X$VERSION kqftab. , kqftap kqftab , kqfvip
kqfviw. kqvrow(). -!
oracle tables21 . X$VERSION :
Listing 7.9: oracle tables
kqftab_element.name: [X$VERSION] ?: [kqvt] 0x4 0x4 0x4 0xc 0xffffc075 0x3
kqftap_param.name=[ADDR] ?: 0x917 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INDX] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INST_ID] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[BANNER] ?: 0x601 0x0 0x0 0x0 0x50 0x0 0x0
kqftap_element.fn1=kqvrow
kqftap_element.fn2=NULL

tracer 6.0.1 , , - 6 ( - qerfxFetch())


X$VERSION.
tracer 6.0.1 cc ( ):
tracer -a:oracle.exe bpf=oracle.exe!_kqvrow,trace:cc
_kqvrow_

proc near

var_7C
var_18
var_14
Dest
var_C
var_8
var_4
arg_8
arg_C
arg_14
arg_18

=
=
=
=
=
=
=
=
=
=
=

byte ptr -7Ch


dword ptr -18h
dword ptr -14h
dword ptr -10h
dword ptr -0Ch
dword ptr -8
dword ptr -4
dword ptr 10h
dword ptr 14h
dword ptr 1Ch
dword ptr 20h

; FUNCTION CHUNK AT .text1:056C11A0 SIZE 00000049 BYTES


push
mov
sub
mov
mov
mov
mov
cmp
mov
jz
mov
mov

21

ebp
ebp, esp
esp, 7Ch
eax, [ebp+arg_14] ; [EBP+1Ch]=1
ecx, TlsIndex
; [69AEB08h]=0
edx, large fs:2Ch
edx, [edx+ecx*4] ; [EDX+ECX*4]=0xc98c938
eax, 2
; EAX=1
eax, [ebp+arg_8] ; [EBP+10h]=0xcdfe554
loc_2CE1288
ecx, [eax]
; [EAX]=0..5
[ebp+var_4], edi ; EDI=0xc98c938

http://yurichev.com/oracle_tables.html

276

7.4. ORACLE RDBMS


loc_2CE10F6:
cmp
ja
mov
mov
mov
mov
mov

7.
; CODE XREF: _kqvrow_+10A
; _kqvrow_+1A9
; ECX=0..5

ecx, 5
loc_56C11C7
edi, [ebp+arg_18] ; [EBP+20h]=0
[ebp+var_14], edx ; EDX=0xc98c938
[ebp+var_8], ebx ; EBX=0
ebx, eax
; EAX=0xcdfe554
[ebp+var_C], esi ; ESI=0xcdfe248

loc_2CE110D:

; CODE XREF: _kqvrow_+29E00E6


mov
edx, ds:off_628B09C[ecx*4] ; [ECX*4+628B09Ch]=0x2ce1116, 0x2ce11ac, 0x2ce11db, 0
x2ce11f6, 0x2ce1236, 0x2ce127a
jmp
edx
; EDX=0x2ce1116, 0x2ce11ac, 0x2ce11db, 0x2ce11f6, 0x2ce1236, 0
x2ce127a
; --------------------------------------------------------------------------loc_2CE1116:

; DATA XREF: .rdata:off_628B09C


push
offset aXKqvvsnBuffer ; "x$kqvvsn buffer"
mov
ecx, [ebp+arg_C] ; [EBP+14h]=0x8a172b4
xor
edx, edx
mov
esi, [ebp+var_14] ; [EBP-14h]=0xc98c938
push
edx
; EDX=0
push
edx
; EDX=0
push
50h
push
ecx
; ECX=0x8a172b4
push
dword ptr [esi+10494h] ; [ESI+10494h]=0xc98cd58
call
_kghalf
; tracing nested maximum level (1) reached, skipping this CALL
mov
esi, ds:__imp__vsnnum ; [59771A8h]=0x61bc49e0
mov
[ebp+Dest], eax ; EAX=0xce2ffb0
mov
[ebx+8], eax
; EAX=0xce2ffb0
mov
[ebx+4], eax
; EAX=0xce2ffb0
mov
edi, [esi]
; [ESI]=0xb200100
mov
esi, ds:__imp__vsnstr ; [597D6D4h]=0x65852148, "- Production"
push
esi
; ESI=0x65852148, "- Production"
mov
ebx, edi
; EDI=0xb200100
shr
ebx, 18h
; EBX=0xb200100
mov
ecx, edi
; EDI=0xb200100
shr
ecx, 14h
; ECX=0xb200100
and
ecx, 0Fh
; ECX=0xb2
mov
edx, edi
; EDI=0xb200100
shr
edx, 0Ch
; EDX=0xb200100
movzx
edx, dl
; DL=0
mov
eax, edi
; EDI=0xb200100
shr
eax, 8
; EAX=0xb200100
and
eax, 0Fh
; EAX=0xb2001
and
edi, 0FFh
; EDI=0xb200100
push
edi
; EDI=0
mov
edi, [ebp+arg_18] ; [EBP+20h]=0
push
eax
; EAX=1
mov
eax, ds:__imp__vsnban ; [597D6D8h]=0x65852100, "Oracle Database 11g Enterprise
Edition Release %d.%d.%d.%d.%d %s"
push
edx
; EDX=0
push
ecx
; ECX=2
push
ebx
; EBX=0xb
mov
ebx, [ebp+arg_8] ; [EBP+10h]=0xcdfe554
push
eax
; EAX=0x65852100, "Oracle Database 11g Enterprise Edition Release
%d.%d.%d.%d.%d %s"
mov
eax, [ebp+Dest] ; [EBP-10h]=0xce2ffb0
push
eax
; EAX=0xce2ffb0
call
ds:__imp__sprintf ; op1=MSVCR80.dll!sprintf tracing nested maximum level (1)
reached, skipping this CALL
add
esp, 38h
mov
dword ptr [ebx], 1

loc_2CE1192:

; CODE XREF: _kqvrow_+FB


; _kqvrow_+128 ...
test
edi, edi
; EDI=0
jnz
__VInfreq__kqvrow
mov
esi, [ebp+var_C] ; [EBP-0Ch]=0xcdfe248
mov
edi, [ebp+var_4] ; [EBP-4]=0xc98c938
mov
eax, ebx
; EBX=0xcdfe554
mov
ebx, [ebp+var_8] ; [EBP-8]=0
lea
eax, [eax+4]
; [EAX+4]=0xce2ffb0, "NLSRTL Version 11.2.0.1.0 - Production", "
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production", "PL/SQL Release 11.2.0.1.0 Production", "TNS for 32-bit Windows: Version 11.2.0.1.0 - Production"

277

7.4. ORACLE RDBMS

7.

loc_2CE11A8:

; CODE XREF: _kqvrow_+29E00F6


mov
esp, ebp
pop
ebp
retn
; EAX=0xcdfe558
; --------------------------------------------------------------------------loc_2CE11AC:

; DATA XREF: .rdata:0628B0A0


mov
edx, [ebx+8]
; [EBX+8]=0xce2ffb0, "Oracle Database 11g Enterprise Edition
Release 11.2.0.1.0 - Production"
mov
dword ptr [ebx], 2
mov
[ebx+4], edx
; EDX=0xce2ffb0, "Oracle Database 11g Enterprise Edition Release
11.2.0.1.0 - Production"
push
edx
; EDX=0xce2ffb0, "Oracle Database 11g Enterprise Edition Release
11.2.0.1.0 - Production"
call
_kkxvsn
; tracing nested maximum level (1) reached, skipping this CALL
pop
ecx
mov
edx, [ebx+4]
; [EBX+4]=0xce2ffb0, "PL/SQL Release 11.2.0.1.0 - Production"
movzx
ecx, byte ptr [edx] ; [EDX]=0x50
test
ecx, ecx
; ECX=0x50
jnz
short loc_2CE1192
mov
edx, [ebp+var_14]
mov
esi, [ebp+var_C]
mov
eax, ebx
mov
ebx, [ebp+var_8]
mov
ecx, [eax]
jmp
loc_2CE10F6
; --------------------------------------------------------------------------loc_2CE11DB:

; DATA XREF: .rdata:0628B0A4


push
0
push
50h
mov
edx, [ebx+8]
; [EBX+8]=0xce2ffb0, "PL/SQL Release 11.2.0.1.0 - Production"
mov
[ebx+4], edx
; EDX=0xce2ffb0, "PL/SQL Release 11.2.0.1.0 - Production"
push
edx
; EDX=0xce2ffb0, "PL/SQL Release 11.2.0.1.0 - Production"
call
_lmxver
; tracing nested maximum level (1) reached, skipping this CALL
add
esp, 0Ch
mov
dword ptr [ebx], 3
jmp
short loc_2CE1192
; --------------------------------------------------------------------------loc_2CE11F6:
mov
mov
mov
push
call
pop
test
jnz
mov
lea
push
push
push
call
add

; DATA XREF: .rdata:0628B0A8


edx, [ebx+8]
; [EBX+8]=0xce2ffb0
[ebp+var_18], 50h
[ebx+4], edx
; EDX=0xce2ffb0
0
_npinli
; tracing nested maximum level (1) reached, skipping this CALL
ecx
eax, eax
; EAX=0
loc_56C11DA
ecx, [ebp+var_14] ; [EBP-14h]=0xc98c938
edx, [ebp+var_18] ; [EBP-18h]=0x50
edx
; EDX=0xd76c93c
dword ptr [ebx+8] ; [EBX+8]=0xce2ffb0
dword ptr [ecx+13278h] ; [ECX+13278h]=0xacce190
_nrtnsvrs
; tracing nested maximum level (1) reached, skipping this CALL
esp, 0Ch

loc_2CE122B:

; CODE XREF: _kqvrow_+29E0118


mov
dword ptr [ebx], 4
jmp
loc_2CE1192
; --------------------------------------------------------------------------loc_2CE1236:
lea
push
push
mov
Production"
mov
Production"
mov
mov
push
push
Production"

; DATA XREF: .rdata:0628B0AC


edx, [ebp+var_7C] ; [EBP-7Ch]=1
edx
; EDX=0xd76c8d8
0
esi, [ebx+8]
; [EBX+8]=0xce2ffb0, "TNS for 32-bit Windows: Version 11.2.0.1.0 [ebx+4], esi

; ESI=0xce2ffb0, "TNS for 32-bit Windows: Version 11.2.0.1.0 -

ecx, 50h
[ebp+var_18], ecx ; ECX=0x50
ecx
; ECX=0x50
esi
; ESI=0xce2ffb0, "TNS for 32-bit Windows: Version 11.2.0.1.0 -

278

7.4. ORACLE RDBMS

7.

call
_lxvers
; tracing nested maximum level (1) reached, skipping this CALL
add
esp, 10h
mov
edx, [ebp+var_18] ; [EBP-18h]=0x50
mov
dword ptr [ebx], 5
test
edx, edx
; EDX=0x50
jnz
loc_2CE1192
mov
edx, [ebp+var_14]
mov
esi, [ebp+var_C]
mov
eax, ebx
mov
ebx, [ebp+var_8]
mov
ecx, 5
jmp
loc_2CE10F6
; --------------------------------------------------------------------------loc_2CE127A:

; DATA XREF: .rdata:0628B0B0


[ebp+var_14] ; [EBP-14h]=0xc98c938
[ebp+var_C] ; [EBP-0Ch]=0xcdfe248
[ebp+var_4] ; [EBP-4]=0xc98c938
ebx
; EBX=0xcdfe554
[ebp+var_8] ; [EBP-8]=0

mov
mov
mov
mov
mov

edx,
esi,
edi,
eax,
ebx,

mov
test
jz
push
push
mov
push
push
call
add

; CODE XREF: _kqvrow_+1F


eax, [eax+8]
; [EAX+8]=0xce2ffb0, "NLSRTL Version 11.2.0.1.0 - Production"
eax, eax
; EAX=0xce2ffb0, "NLSRTL Version 11.2.0.1.0 - Production"
short loc_2CE12A7
offset aXKqvvsnBuffer ; "x$kqvvsn buffer"
eax
; EAX=0xce2ffb0, "NLSRTL Version 11.2.0.1.0 - Production"
eax, [ebp+arg_C] ; [EBP+14h]=0x8a172b4
eax
; EAX=0x8a172b4
dword ptr [edx+10494h] ; [EDX+10494h]=0xc98cd58
_kghfrf
; tracing nested maximum level (1) reached, skipping this CALL
esp, 10h

loc_2CE1288:

loc_2CE12A7:

_kqvrow_

; CODE XREF: _kqvrow_+1C1


xor
mov
pop
retn
endp

eax, eax
esp, ebp
ebp
; EAX=0

, . - ,
:
1
2
3
4
5

vsnstr, vsnnum, vsnban. sprintf().


kkxvsn().
lmxver().
npinli(), nrtnsvrs().
lxvers().

- .

7.4.2

X$KSMLRU Oracle RDBMS

Diagnosing and Resolving Error ORA-04031 on the Shared Pool or Other Memory Pools [Video] [ID
146599.1] :

There is a fixed table called X$KSMLRU that tracks allocations in the shared pool that cause
other objects in the shared pool to be aged out. This fixed table can be used to identify what
is causing the large allocation.
If many objects are being periodically flushed from the shared pool then this will cause
response time problems and will likely cause library cache latch contention problems when
the objects are reloaded into the shared pool.
One unusual thing about the X$KSMLRU fixed table is that the contents of the fixed table
are erased whenever someone selects from the fixed table. This is done since the fixed table
279

7.4. ORACLE RDBMS

7.

stores only the largest allocations that have occurred. The values are reset after being selected
so that subsequent large allocations can be noted even if they were not quite as large as others
that occurred previously. Because of this resetting, the output of selecting from this table should
be carefully kept since it cannot be retrieved back after the query is issued.

, , , -
. , ?
kqftab kqftap oracle tables22 , X$, , - ksmlrs():
Listing 7.10: oracle tables
kqftab_element.name: [X$KSMLRU] ?: [ksmlr] 0x4 0x64 0x11 0xc 0xffffc0bb 0x5
kqftap_param.name=[ADDR] ?: 0x917 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INDX] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INST_ID] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[KSMLRIDX] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[KSMLRDUR] ?: 0xb02 0x0 0x0 0x0 0x4 0x4 0x0
kqftap_param.name=[KSMLRSHRPOOL] ?: 0xb02 0x0 0x0 0x0 0x4 0x8 0x0
kqftap_param.name=[KSMLRCOM] ?: 0x501 0x0 0x0 0x0 0x14 0xc 0x0
kqftap_param.name=[KSMLRSIZ] ?: 0x2 0x0 0x0 0x0 0x4 0x20 0x0
kqftap_param.name=[KSMLRNUM] ?: 0x2 0x0 0x0 0x0 0x4 0x24 0x0
kqftap_param.name=[KSMLRHON] ?: 0x501 0x0 0x0 0x0 0x20 0x28 0x0
kqftap_param.name=[KSMLROHV] ?: 0xb02 0x0 0x0 0x0 0x4 0x48 0x0
kqftap_param.name=[KSMLRSES] ?: 0x17 0x0 0x0 0x0 0x4 0x4c 0x0
kqftap_param.name=[KSMLRADU] ?: 0x2 0x0 0x0 0x0 0x4 0x50 0x0
kqftap_param.name=[KSMLRNID] ?: 0x2 0x0 0x0 0x0 0x4 0x54 0x0
kqftap_param.name=[KSMLRNSD] ?: 0x2 0x0 0x0 0x0 0x4 0x58 0x0
kqftap_param.name=[KSMLRNCD] ?: 0x2 0x0 0x0 0x0 0x4 0x5c 0x0
kqftap_param.name=[KSMLRNED] ?: 0x2 0x0 0x0 0x0 0x4 0x60 0x0
kqftap_element.fn1=ksmlrs
kqftap_element.fn2=NULL

, tracer 6.0.1 - ,
X$KSMLRU.
- ksmsplu_sp() ksmsplu_jp(),
ksmsplu(). - ksmsplu() memset():
Listing 7.11: ksm.o
...
.text:00434C50 loc_434C50:
.text:00434C50
.text:00434C53
.text:00434C55
.text:00434C57
.text:00434C5A
.text:00434C5C
.text:00434C5F
.text:00434C62
.text:00434C68
.text:00434C6B
.text:00434C6E
.text:00434C71
.text:00434C74
.text:00434C7A
.text:00434C7F
.text:00434C81
.text:00434C82
.text:00434C87
.text:00434C8A
.text:00434C8C
.text:00434C8D
.text:00434C8D _ksmsplu
22

mov
mov
mov
mov
mov
add
mov
jnz
mov
mov
mov
mov
lea
push
push
push
call
add
mov
pop
retn
endp

; DATA XREF: .rdata:off_5E50EA8


edx, [ebp-4]
[eax], esi
esi, [edi]
[eax+4], esi
[edi], eax
edx, 1
[ebp-4], edx
loc_434B7D
ecx, [ebp+14h]
ebx, [ebp-10h]
esi, [ebp-0Ch]
edi, [ebp-8]
eax, [ecx+8Ch]
370h
; Size
0
; Val
eax
; Dst
__intel_fast_memset
esp, 0Ch
esp, ebp
ebp

http://yurichev.com/oracle_tables.html

280

7.4. ORACLE RDBMS


7.
(memset (block, 0, size))
. , memset() , ?
tracer 6.0.1 : 0x434C7A ( - memset()) , tracer 6.0.1
(EIP) , memset()
( 0x434C8A): , ,
0x434C7A 0x434C8A.
tracer -a:oracle.exe bpx=oracle.exe!0x00434C7A,set(eip,0x00434C8A)

(: win32- Oracle RDBMS 11.2)


, X$KSMLRU ,
!
(" ") production-.
, ,
, !

7.4.3

V$TIMER Oracle RDBMS

V$TIMER fixed view, - :

V$TIMER displays the elapsed time in hundredths of a second. Time is measured since
the beginning of the epoch, which is operating system specific, and wraps around to 0 again
whenever the value overflows four bytes (roughly 497 days).

( Oracle RDBMS 23 )
Oracle Win32 Linux. , ?
, , , X$KSUTM.
SQL> select * from V$FIXED_VIEW_DEFINITION where view_name=V$TIMER;
VIEW_NAME
-----------------------------VIEW_DEFINITION
-------------------------------------------------------------------------------V$TIMER
select HSECS from GV$TIMER where inst_id = USERENV(Instance)
SQL> select * from V$FIXED_VIEW_DEFINITION where view_name=GV$TIMER;
VIEW_NAME
-----------------------------VIEW_DEFINITION
-------------------------------------------------------------------------------GV$TIMER
select inst_id,ksutmtim from x$ksutm

, kqftab/kqftap ,
:
Listing 7.12: oracle tables
kqftab_element.name: [X$KSUTM] ?: [ksutm] 0x1 0x4 0x4 0x0 0xffffc09b 0x3
kqftap_param.name=[ADDR] ?: 0x10917 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INDX] ?: 0x20b02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INST_ID] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[KSUTMTIM] ?: 0x1302 0x0 0x0 0x0 0x4 0x0 0x1e
23

http://docs.oracle.com/cd/B28359_01/server.111/b28320/dynviews_3104.htm

281

7.4. ORACLE RDBMS

7.

kqftap_element.fn1=NULL
kqftap_element.fn2=NULL

KSUTMTIM, :
kqfd_DRN_ksutm_c proc near
arg_0
arg_8
arg_C

= dword ptr
= dword ptr
= dword ptr

push
mov
push
push
push
push
push
call
add
mov
pop
retn
kqfd_DRN_ksutm_c endp

; DATA XREF: .rodata:0805B4E8


8
10h
14h

ebp
ebp, esp
[ebp+arg_C]
offset ksugtm
offset _2__STRING_1263_0 ; "KSUTMTIM"
[ebp+arg_8]
[ebp+arg_0]
kqfd_cfui_drain
esp, 14h
esp, ebp
ebp

- kqfd_DRN_ksutm_c() kqfd_tab_registry_0 :
dd
dd
dd
dd
dd
dd

offset
offset
offset
0
0
offset

_2__STRING_62_0 ; "X$KSUTM"
kqfd_OPN_ksutm_c
kqfd_tabl_fetch

kqfd_DRN_ksutm_c

- ksugtm(). , ( Linux x86):


Listing 7.13: ksu.o
ksugtm

proc near

var_1C
arg_4

= byte ptr -1Ch


= dword ptr 0Ch

ksugtm

push
mov
sub
lea
push
call
pop
mov
mov
mov
mov
pop
retn
endp

ebp
ebp, esp
esp, 1Ch
eax, [ebp+var_1C]
eax
slgcs
ecx
edx, [ebp+arg_4]
[edx], eax
eax, 4
esp, ebp
ebp

win32- .
? :
tracer -a:oracle.exe bpf=oracle.exe!_ksugtm,args:2,dump_args:0x4

:
SQL> select * from V$TIMER;
HSECS
---------27294929
SQL> select * from V$TIMER;
HSECS
---------27295006

282

7.4. ORACLE RDBMS

7.

SQL> select * from V$TIMER;


HSECS
---------27295167

Listing 7.14: tracer


TID=2428|(0) oracle.exe!_ksugtm
x56bb6d5))
Argument 2/2
0D76C5F0: 38 C9
TID=2428|(0) oracle.exe!_ksugtm
Argument 2/2 difference
00000000: D1 7C A0 01
TID=2428|(0) oracle.exe!_ksugtm
x56bb6d5))
Argument 2/2
0D76C5F0: 38 C9
TID=2428|(0) oracle.exe!_ksugtm
Argument 2/2 difference
00000000: 1E 7D A0 01
TID=2428|(0) oracle.exe!_ksugtm
x56bb6d5))
Argument 2/2
0D76C5F0: 38 C9
TID=2428|(0) oracle.exe!_ksugtm
Argument 2/2 difference
00000000: BF 7D A0 01

6.0.1

(0x0, 0xd76c5f0) (called from oracle.exe!__VInfreq__qerfxFetch+0xfad (0

"8.

"

() -> 0x4 (0x4)


".|..
"
(0x0, 0xd76c5f0) (called from oracle.exe!__VInfreq__qerfxFetch+0xfad (0

"8.

"

() -> 0x4 (0x4)


".}..
"
(0x0, 0xd76c5f0) (called from oracle.exe!__VInfreq__qerfxFetch+0xfad (0

"8.

"

".}..

"

() -> 0x4 (0x4)

, SQL*Plus, .
- slgcs() (Linux x86):
slgcs

proc near

var_4
arg_0

= dword ptr -4
= dword ptr 8

slgcs

push
mov
push
mov
mov
call
pop
nop
mov
mov
call
push
push
push
push
call
mov
add
mov
pop
retn
endp

ebp
ebp, esp
esi
[ebp+var_4], ebx
eax, [ebp+arg_0]
$+5
ebx
; PIC mode
ebx, offset _GLOBAL_OFFSET_TABLE_
dword ptr [eax], 0
sltrgatime64
; PIC mode
0
0Ah
edx
eax
__udivdi3
; PIC mode
ebx, [ebp+var_4]
esp, 10h
esp, ebp
ebp

( sltrgatime64() 10 (1.12))
win32-:
_slgcs

proc near
db
nop
push
mov
mov
mov
call
mov

; CODE XREF: _dbgefgHtElResetCount+15


; _dbgerRunActions+1528

66h
ebp
ebp, esp
eax, [ebp+8]
dword ptr [eax], 0
ds:__imp__GetTickCount@0 ; GetTickCount()
edx, eax

283

7.4. ORACLE RDBMS

_slgcs

mov
mul
shr
mov
mov
pop
retn
endp

7.
eax,
edx
edx,
eax,
esp,
ebp

0CCCCCCCDh
3
edx
ebp

GetTickCount() 24 10 (1.12).
! win32- Linux x86 ,
- .
Drain , , . , .
kqfd_tab_registry_0 oracle tables25 , ,
-, , :
[X$KSUTM] [kqfd_OPN_ksutm_c] [kqfd_tabl_fetch] [NULL] [NULL] [kqfd_DRN_ksutm_c]
[X$KSUSGIF] [kqfd_OPN_ksusg_c] [kqfd_tabl_fetch] [NULL] [NULL] [kqfd_DRN_ksusg_c]

OPN, , open, DRN, , drain.

24
25

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx
http://yurichev.com/oracle_tables.html

284

8.

8.1

Compiler intrinsic

- -.
. , CPU.
, /++ , CPU . , MSVC _rotl() _rotr()1 ,
x86- ROL/ROR.
- SSE- .

8.2

Intel C++ 10.1 Oracle RDBMS 11.2 Linux86, JZ


, JZ . JZ , .
Listing 8.1: kdli.o libserver11.a
.text:08114CF1
loc_8114CF1:
__PGOSF539_kdlimemSer+89A
.text:08114CF1
.text:08114CF1 8B 45 08
.text:08114CF4 0F B6 50 14
.text:08114CF8 F6 C2 01
.text:08114CFB 0F 85 17 08 00 00
.text:08114D01 85 C9
.text:08114D03 0F 84 8A 00 00 00
.text:08114D09 0F 84 09 08 00 00
.text:08114D0F 8B 53 08
.text:08114D12 89 55 FC
.text:08114D15 31 C0
.text:08114D17 89 45 F4
.text:08114D1A 50
.text:08114D1B 52
.text:08114D1C E8 03 54 00 00
.text:08114D21 83 C4 08

; CODE XREF:

mov
movzx
test
jnz
test
jz
jz
mov
mov
xor
mov
push
push
call
add

; __PGOSF539_kdlimemSer+3994
eax, [ebp+arg_0]
edx, byte ptr [eax+14h]
dl, 1
loc_8115518
ecx, ecx
loc_8114D93
loc_8115518
edx, [ebx+8]
[ebp+var_4], edx
eax, eax
[ebp+var_C], eax
eax
edx
len2nbytes
esp, 8

Listing 8.2:
.text:0811A2A5
.text:0811A2A5
.text:0811A2A5
.text:0811A2A8
.text:0811A2AB
.text:0811A2AF
.text:0811A2B2
1

loc_811A2A5:
8B
8B
0F
F6
75

7D
7F
B6
C2
3E

08
10
57 14
01

; CODE XREF: kdliSerLengths+11C


; kdliSerLengths+1C1
mov
mov
movzx
test
jnz

edi, [ebp+arg_0]
edi, [edi+10h]
edx, byte ptr [edi+14h]
dl, 1
short loc_811A2F2

http://msdn.microsoft.com/en-us/library/5cc576c4.aspx

285

8.3. OPENMP
.text:0811A2B4
.text:0811A2B7
.text:0811A2B9
.text:0811A2BB
.text:0811A2BD
.text:0811A2C0

8.
83
74
74
6A
FF
E8

E0 01
1F
37
00
71 08
5F FE FF FF

and
jz
jz
push
push
call

eax, 1
short loc_811A2D8
short loc_811A2F2
0
dword ptr [ecx+8]
len2nbytes

, , (
).
(1.15.2).
, , , ,
.

8.3

OpenMP

OpenMP .
, nonce.
, nonce ,
- . , , Bitcoin nonce,
. proof of work
2 (.., -
).
Bitcoin, hello, world!_
, hello, world!_<number> SHA512
3 .
:
#include
#include
#include
#include
#include

<stdio.h>
<string.h>
<stdlib.h>
<time.h>
"sha512.h"

int found=0;
int32_t checked=0;
int32_t* __min;
int32_t* __max;
time_t start;
#ifdef __GNUC__
#define min(X,Y) ((X) < (Y) ? (X) : (Y))
#define max(X,Y) ((X) > (Y) ? (X) : (Y))
#endif
void check_nonce (int32_t nonce)
{
uint8_t buf[32];
struct sha512_ctx ctx;
uint8_t res[64];
// update statistics
int t=omp_get_thread_num();
if (__min[t]==-1)
__min[t]=nonce;
if (__max[t]==-1)
__max[t]=nonce;
__min[t]=min(__min[t], nonce);
__max[t]=max(__max[t], nonce);
// idle if valid nonce found
2

https://ru.wikipedia.org/wiki/Proof-of-work

286

8.3. OPENMP

8.

if (found)
return;
memset (buf, 0, sizeof(buf));
sprintf (buf, "hello, world!_%d", nonce);
sha512_init_ctx (&ctx);
sha512_process_bytes (buf, strlen(buf), &ctx);
sha512_finish_ctx (&ctx, &res);
if (res[0]==0 && res[1]==0 && res[2]==0)
{
printf ("found (thread %d): [%s]. seconds spent=%d\n", t, buf, time(NULL)-start);
found=1;
};
#pragma omp atomic
checked++;
#pragma omp critical
if ((checked % 100000)==0)
printf ("checked=%d\n", checked);
};
int main()
{
int32_t i;
int threads=omp_get_max_threads();
printf ("threads=%d\n", threads);
__min=(int32_t*)malloc(threads*sizeof(int32_t));
__max=(int32_t*)malloc(threads*sizeof(int32_t));
for (i=0; i<threads; i++)
__min[i]=__max[i]=-1;
start=time(NULL);
#pragma omp parallel for
for (i=0; i<INT32_MAX; i++)
check_nonce (i);
for (i=0; i<threads; i++)
printf ("__min[%d]=0x%08x __max[%d]=0x%08x\n", i, __min[i], i, __max[i]);
free(__min); free(__max);
};

check_nonce() , SHA512 3 .
:
#pragma omp parallel for
for (i=0; i<INT32_MAX; i++)
check_nonce (i);

, , #pragma check_nonce()
0 INT32_MAX (0x7fffffff 2147483647). #pragma, ,
, CPU.
3 MSVC 2012:
cl openmp_example.c sha512.obj /openmp /O1 /Zi /Faopenmp_example.asm

GCC:
gcc -fopenmp 2.c sha512.c -S -masm=intel

8.3.1

MSVC

MSVC 2012 :
3

sha512.c u64.h OpenSSL: http://www.openssl.org/source/

287

8.3. OPENMP

8.
Listing 8.3: MSVC 2012

push
push
push
call
add

OFFSET _main$omp$1
0
1
__vcomp_fork
esp, 16

; 00000010H

- vcomp OpenMP vcomp*.dll.


.
_main$omp$1:
Listing 8.4: MSVC 2012
$T1 = -8
$T2 = -4
_main$omp$1 PROC
push
ebp
mov
ebp, esp
push
ecx
push
ecx
push
esi
lea
eax, DWORD PTR $T2[ebp]
push
eax
lea
eax, DWORD PTR $T1[ebp]
push
eax
push
1
push
1
push
2147483646
push
0
call
__vcomp_for_static_simple_init
mov
esi, DWORD PTR $T1[ebp]
add
esp, 24
jmp
SHORT $LN6@main$omp$1
$LL2@main$omp$1:
push
esi
call
_check_nonce
pop
ecx
inc
esi
$LN6@main$omp$1:
cmp
esi, DWORD PTR $T2[ebp]
jle
SHORT $LL2@main$omp$1
call
__vcomp_for_static_end
pop
esi
leave
ret
0
_main$omp$1 ENDP

; size = 4
; size = 4
; COMDAT

; 7ffffffeH

; 00000018H

- , CPU. vcomp_for_static_simple_init()
for() , . $T1 $T2.
7ffffffeh ( 2147483646) - vcomp_for_static_simple_init() , .
- check_nonce() .
- check_nonce() , - .
:
threads=4
...
checked=2800000
checked=3000000
checked=3200000
checked=3300000
found (thread 3): [hello, world!_1611446522]. seconds spent=3
__min[0]=0x00000000 __max[0]=0x1fffffff
__min[1]=0x20000000 __max[1]=0x3fffffff
__min[2]=0x40000000 __max[2]=0x5fffffff
__min[3]=0x60000000 __max[3]=0x7ffffffe

, , 3 :

288

8.3. OPENMP

8.

C:\...\sha512sum test
000000f4a8fac5a4ed38794da4c1e39f54279ad5d9bb3c5465cdf57adaf60403df6e3fe6019f5764fc9975e505a7395fed78
0fee50eb38dd4c0279cb114672e2 *test

2..3 4- Intel Xeon E3-1220 3.10 GHz. task manager


5 : + 4 . ,
. . CPU 4 ,
OpenMP 4 .
, 4
. , , .
.
:
#pragma omp atomic
checked++;
#pragma omp critical
if ((checked % 100000)==0)
printf ("checked=%d\n", checked);

Listing 8.5: MSVC 2012


push
edi
push
OFFSET _checked
call
__vcomp_atomic_add_i4
; Line 55
push
OFFSET _$vcomp$critsect$
call
__vcomp_enter_critsect
add
esp, 12
; 0000000cH
; Line 56
mov
ecx, DWORD PTR _checked
mov
eax, ecx
cdq
mov
esi, 100000
; 000186a0H
idiv
esi
test
edx, edx
jne
SHORT $LN1@check_nonc
; Line 57
push
ecx
push
OFFSET ??_C@_0M@NPNHLIOO@checked?$DN?$CFd?6?$AA@
call
_printf
pop
ecx
pop
ecx
$LN1@check_nonc:
push
DWORD PTR _$vcomp$critsect$
call
__vcomp_leave_critsect
pop
ecx

, - vcomp_atomic_add_i4() vcomp*.dll -
LOCK XADD4 .
vcomp_enter_critsect() - win32 API EnterCriticalSection()
5.

8.3.2

GCC

GCC 4.8.1 , ,
GCC .
Listing 8.6: GCC 4.8.1
mov
call
mov
call
call
4
5

edi, OFFSET FLAT:main._omp_fn.0


GOMP_parallel_start
edi, 0
main._omp_fn.0
GOMP_parallel_end

LOCK : 11.5.6
: 5.3

289

8.3. OPENMP
8.
MSVC, GCC 4 , . 4 5 MSVC.
- main._omp_fn.0:
Listing 8.7: GCC 4.8.1
main._omp_fn.0:
push
mov
push
sub
mov
call
mov
call
mov
mov
cdq
idiv
mov
mov
cdq
idiv
mov
cmp
jl
.L18:
imul
mov
add
lea
cmp
jge
mov
.L17:
mov
mov
call
add
cmp
jl
jmp
.L15:
mov
add
jmp
.L14:
add
pop
pop
ret

rbp
rbp, rsp
rbx
rsp, 40
QWORD PTR [rbp-40], rdi
omp_get_num_threads
ebx, eax
omp_get_thread_num
esi, eax
eax, 2147483647 ; 0x7FFFFFFF
ebx
ecx, eax
eax, 2147483647 ; 0x7FFFFFFF
ebx
eax, edx
esi, eax
.L15
esi, ecx
edx, esi
eax, edx
ebx, [rax+rcx]
eax, ebx
.L14
DWORD PTR [rbp-20], eax
eax, DWORD PTR [rbp-20]
edi, eax
check_nonce
DWORD PTR [rbp-20], 1
DWORD PTR [rbp-20], ebx
.L17
.L14
eax, 0
ecx, 1
.L18
rsp, 40
rbx
rbp

: omp_get_num_threads() omp_get_thread_num()
, ,
. check_nonce().
GCC LOCK ADD , MSVC
- DLL:
Listing 8.8: GCC 4.8.1
lock add
DWORD PTR checked[rip], 1
call
GOMP_critical_start
mov
ecx, DWORD PTR checked[rip]
mov
edx, 351843721
mov
eax, ecx
imul
edx
sar
edx, 13
mov
eax, ecx
sar
eax, 31
sub
edx, eax
mov
eax, edx
imul
eax, eax, 100000
sub
ecx, eax
mov
eax, ecx

290

8.3. OPENMP

8.

test
jne
mov
mov
mov
mov
call

eax, eax
.L7
eax, DWORD PTR checked[rip]
esi, eax
edi, OFFSET FLAT:.LC2 ; "checked=%d\n"
eax, 0
printf

call

GOMP_critical_end

.L7:

- GOMP GNU OpenMP. vcomp*.dll,


: https://github.com/mirrors/gcc/tree/master/libgomp.

291

9.


9.1
9.1.1

Windows

[23].

9.1.2

/++

[13].

9.1.3

x86 / x86-64

[11], [1]

9.1.4

ARM

ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.
architecture.reference/index.html

9.2
9.2.1

Windows

Microsoft: Raymond Chen


http://www.nynaeve.net/

292

10.

10

, , :
1) ? .
2) /++.
.

10.1

10.1.1

1.1

. OpenWatcom This is standard C library function.


Source code taken from OpenWatcom.
MSVC 2010
_TEXT
SEGMENT
_input$ = 8
; size = 1
_f PROC
push
ebp
mov
ebp, esp
movsx eax, BYTE PTR _input$[ebp]
cmp
eax, 97
; 00000061H
jl
SHORT $LN1@f
movsx ecx, BYTE PTR _input$[ebp]
cmp
ecx, 122
; 0000007aH
jg
SHORT $LN1@f
movsx edx, BYTE PTR _input$[ebp]
sub
edx, 32
; 00000020H
mov
BYTE PTR _input$[ebp], dl
$LN1@f:
mov
al, BYTE PTR _input$[ebp]
pop
ebp
ret
0
_f ENDP
_TEXT
ENDS

GCC 4.4.1 + -O3


_f

proc near

input

= dword ptr
push
mov
movzx
lea
cmp
ja
sub

ebp
ebp, esp
eax, byte ptr [ebp+input]
edx, [eax-61h]
dl, 19h
short loc_80483F2
eax, 20h

293

10.1.

10.

loc_80483F2:
pop
retn
endp

_f

ebp

Keil (ARM) + -O3


SUB
CMP
SUBLS
ANDLS
BX

r1,r0,#0x61
r1,#0x19
r0,r0,#0x20
r0,r0,#0xff
lr

Keil (thumb) + -O3


MOVS
SUBS
CMP
BHI
SUBS
LSLS
LSRS

r1,r0
r1,r1,#0x61
r1,#0x19
|L0.14|
r0,r0,#0x20
r0,r0,#24
r0,r0,#24

BX

lr

|L0.14|

10.1.2

1.2

. OpenWatcom This
is also standard C library function. Source code is taken from OpenWatcom and modified slightly.
: isspace() isdigit().
MSVC 2010 + /Ox
EXTRN
_isdigit:PROC
EXTRN
_isspace:PROC
EXTRN
___ptr_check:PROC
; Function compile flags: /Ogtpy
_TEXT
SEGMENT
_p$ = 8
; size = 4
_f
PROC
push
ebx
push
esi
mov
esi, DWORD PTR _p$[esp+4]
push
edi
push
0
push
esi
call
___ptr_check
mov
eax, DWORD PTR [esi]
push
eax
call
_isspace
add
esp, 12
; 0000000cH
test
eax, eax
je
SHORT $LN6@f
npad
2
$LL7@f:
mov
ecx, DWORD PTR [esi+4]
add
esi, 4
push
ecx
call
_isspace
add
esp, 4
test
eax, eax
jne
SHORT $LL7@f
$LN6@f:
mov
bl, BYTE PTR [esi]
cmp
bl, 43
; 0000002bH

294

10.1.

10.

je
SHORT $LN4@f
cmp
bl, 45
jne
SHORT $LN5@f
$LN4@f:
add
esi, 4
$LN5@f:
mov
edx, DWORD PTR
push
edx
xor
edi, edi
call
_isdigit
add
esp, 4
test
eax, eax
je
SHORT $LN2@f
$LL3@f:
mov
ecx, DWORD PTR
mov
edx, DWORD PTR
add
esi, 4
lea
eax, DWORD PTR
push
edx
lea
edi, DWORD PTR
call
_isdigit
add
esp, 4
test
eax, eax
jne
SHORT $LL3@f
$LN2@f:
cmp
bl, 45
jne
SHORT $LN14@f
neg
edi
$LN14@f:
mov
eax, edi
pop
edi
pop
esi
pop
ebx
ret
0
_f
ENDP
_TEXT
ENDS

; 0000002dH

[esi]

[esi]
[esi+4]
[edi+edi*4]
[ecx+eax*2-48]

; 0000002dH

GCC 4.4.1
, GCC isspace() isdigit() inline-
.
_f

proc near

var_10
var_9
input

= dword ptr -10h


= byte ptr -9
= dword ptr 8
push
mov
sub
jmp

ebp
ebp, esp
esp, 18h
short loc_8048410

add

[ebp+input], 4

call
mov
mov
mov
add
lea
movzx
movzx
and
test
jnz
mov
mov
mov
cmp
jz
cmp
jnz

___ctype_b_loc
edx, [eax]
eax, [ebp+input]
eax, [eax]
eax, eax
eax, [edx+eax]
eax, word ptr [eax]
eax, ax
eax, 2000h
eax, eax
short loc_804840C
eax, [ebp+input]
eax, [eax]
[ebp+var_9], al
[ebp+var_9], +
short loc_8048444
[ebp+var_9], -
short loc_8048448

loc_804840C:

loc_8048410:

295

10.1.

10.

loc_8048444:
add

[ebp+input], 4

mov
jmp

[ebp+var_10], 0
short loc_8048471

mov
mov
shl
add
add
mov
mov
mov
lea
sub
mov
add

edx, [ebp+var_10]
eax, edx
eax, 2
eax, edx
eax, eax
edx, eax
eax, [ebp+input]
eax, [eax]
eax, [edx+eax]
eax, 30h
[ebp+var_10], eax
[ebp+input], 4

call
mov
mov
mov
add
lea
movzx
movzx
and
test
jnz
cmp
jnz
neg

___ctype_b_loc
edx, [eax]
eax, [ebp+input]
eax, [eax]
eax, eax
eax, [edx+eax]
eax, word ptr [eax]
eax, ax
eax, 800h
eax, eax
short loc_8048451
[ebp+var_9], 2Dh
short loc_804849A
[ebp+var_10]

mov
leave
retn
endp

eax, [ebp+var_10]

loc_8048448:

loc_8048451:

loc_8048471:

loc_804849A:

_f

Keil (ARM) + -O3


PUSH
MOV
BL
LDR

{r4,lr}
r4,r0
__rt_ctype_table
r2,[r0,#0]

LDR
LDRB
TST
ADDNE
BNE
LDRB
MOV
CMP
CMPNE
ADDEQ
B

r0,[r4,#0]
r0,[r2,r0]
r0,#1
r4,r4,#4
|L0.16|
r1,[r4,#0]
r0,#0
r1,#0x2b
r1,#0x2d
r4,r4,#4
|L0.76|

ADD
ADD
SUB
ADD

r0,r0,r0,LSL #2
r0,r3,r0,LSL #1
r0,r0,#0x30
r4,r4,#4

LDR
LDRB
CMP
BEQ
CMP
RSBEQ

r3,[r4,#0]
r12,[r2,r3]
r12,#0x20
|L0.60|
r1,#0x2d
r0,r0,#0

|L0.16|

|L0.60|

|L0.76|

296

10.1.
POP

10.

{r4,pc}

Keil (thumb) + -O3


PUSH
MOVS
BL
LDR
B

{r4-r6,lr}
r4,r0
__rt_ctype_table
r2,[r0,#0]
|L0.14|

ADDS

r4,r4,#4

LDR
LDRB
LSLS
BNE
LDRB
CMP
BEQ
CMP
BNE

r0,[r4,#0]
r0,[r2,r0]
r0,r0,#31
|L0.12|
r1,[r4,#0]
r1,#0x2b
|L0.32|
r1,#0x2d
|L0.34|

ADDS

r4,r4,#4

MOVS
B

r0,#0
|L0.48|

MOVS
MULS
ADDS
SUBS
ADDS

r5,#0xa
r0,r5,r0
r4,r4,#4
r0,r0,#0x30
r0,r3,r0

LDR
LDRB
CMP
BEQ
CMP
BNE
RSBS

r3,[r4,#0]
r5,[r2,r3]
r5,#0x20
|L0.38|
r1,#0x2d
|L0.62|
r0,r0,#0

POP

{r4-r6,pc}

|L0.12|
|L0.14|

|L0.32|
|L0.34|

|L0.38|

|L0.48|

|L0.62|

10.1.3

1.3

, , , .
MSVC 2010 .
, - , ,
( ) .
MSVC 2010 + /Ox
_BSS
_v
_BSS

SEGMENT
01H DUP (?)
ENDS

DD

_TEXT
SEGMENT
_s$ = 8
; size = 4
f1
PROC
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR _s$[ebp]
mov
DWORD PTR _v, eax
pop
ebp
ret
0
f1
ENDP
_TEXT
ENDS
PUBLIC
f2

297

10.1.

10.

_TEXT
SEGMENT
f2
PROC
push
ebp
mov
ebp, esp
mov
eax, DWORD PTR _v
imul
eax, 214013
;
add
eax, 2531011
;
mov
DWORD PTR _v, eax
mov
eax, DWORD PTR _v
shr
eax, 16
;
and
eax, 32767
;
pop
ebp
ret
0
f2
ENDP
_TEXT
ENDS
END

000343fdH
00269ec3H

00000010H
00007fffH

GCC 4.4.1
f1

public f1
proc near

arg_0

= dword ptr

f1

push
mov
mov
mov
pop
retn
endp

ebp
ebp, esp
eax, [ebp+arg_0]
ds:v, eax
ebp

public f2
proc near
push
ebp
mov
ebp, esp
mov
eax, ds:v
imul
eax, 343FDh
add
eax, 269EC3h
mov
ds:v, eax
mov
eax, ds:v
shr
eax, 10h
and
eax, 7FFFh
pop
ebp
retn
endp

f2

f2
bss

segment dword public BSS use32


assume cs:_bss
dd ?
ends

bss

Keil (ARM) + -O3


f1 PROC
LDR
STR
BX
ENDP

r1,|L0.52|
r0,[r1,#0]
lr

LDR
LDR
LDR
MUL
LDR
ADD
STR
MVN
AND

r0,|L0.52|
r2,|L0.56|
r1,[r0,#0] ; v
r1,r2,r1
r2,|L0.60|
r1,r1,r2
r1,[r0,#0] ; v
r0,#0x8000
r0,r0,r1,LSR #16

; v

f2 PROC

298

10.1.
BX
ENDP

lr

DCD

||.data||

DCD

0x000343fd

DCD

0x00269ec3

10.

|L0.52|
|L0.56|
|L0.60|

Keil (thumb) + -O3


f1 PROC
LDR
STR
BX
ENDP

r1,|L0.28|
r0,[r1,#0]
lr

LDR
LDR
LDR
MULS
LDR
ADDS
STR
LSLS
LSRS
BX
ENDP

r0,|L0.28|
r2,|L0.32|
r1,[r0,#0]
r1,r2,r1
r2,|L0.36|
r1,r1,r2
r1,[r0,#0]
r0,r1,#1
r0,r0,#17
lr

DCD

||.data||

DCD

0x000343fd

DCD

0x00269ec3

; v

f2 PROC

; v

; v

|L0.28|
|L0.32|
|L0.36|

10.1.4

1.4

. MSVC 2010.
MSVC 2010 + /Ox
PUBLIC
_f
_TEXT
SEGMENT
_arg1$ = 8
; size = 4
_arg2$ = 12
; size = 4
_f
PROC
push
esi
mov
esi, DWORD PTR _arg1$[esp]
push
edi
mov
edi, DWORD PTR _arg2$[esp+4]
cmp
BYTE PTR [edi], 0
mov
eax, esi
je
SHORT $LN7@f
mov
dl, BYTE PTR [esi]
push
ebx
test
dl, dl
je
SHORT $LN4@f
sub
esi, edi
npad
6
$LL5@f:
mov
ecx, edi
test
dl, dl
je
SHORT $LN2@f
$LL3@f:
mov
dl, BYTE PTR [ecx]
test
dl, dl

299

10.1.

10.

je
SHORT $LN14@f
movsx ebx, BYTE PTR [esi+ecx]
movsx edx, dl
sub
ebx, edx
jne
SHORT $LN2@f
inc
ecx
cmp
BYTE PTR [esi+ecx], bl
jne
SHORT $LL3@f
$LN2@f:
cmp
BYTE PTR [ecx], 0
je
SHORT $LN14@f
mov
dl, BYTE PTR [eax+1]
inc
eax
inc
esi
test
dl, dl
jne
SHORT $LL5@f
xor
eax, eax
pop
ebx
pop
edi
pop
esi
ret
0
_f
ENDP
_TEXT
ENDS
END

GCC 4.4.1
f

public f
proc near

var_C
var_8
var_4
arg_0
arg_4

=
=
=
=
=

dword
dword
dword
dword
dword

ptr -0Ch
ptr -8
ptr -4
ptr 8
ptr 0Ch

push
mov
sub
mov
mov
mov
movzx
test
jnz
mov
jmp

ebp
ebp, esp
esp, 10h
eax, [ebp+arg_0]
[ebp+var_4], eax
eax, [ebp+arg_4]
eax, byte ptr [eax]
al, al
short loc_8048443
eax, [ebp+arg_0]
short locret_8048453

mov
mov
mov
mov
jmp

eax, [ebp+var_4]
[ebp+var_8], eax
eax, [ebp+arg_4]
[ebp+var_C], eax
short loc_804840A

add
add

[ebp+var_8], 1
[ebp+var_C], 1

mov
movzx
test
jz
mov
movzx
test
jz
mov
movzx
mov
movzx
cmp
jz

eax, [ebp+var_8]
eax, byte ptr [eax]
al, al
short loc_804842E
eax, [ebp+var_C]
eax, byte ptr [eax]
al, al
short loc_804842E
eax, [ebp+var_8]
edx, byte ptr [eax]
eax, [ebp+var_C]
eax, byte ptr [eax]
dl, al
short loc_8048402

loc_80483F4:

loc_8048402:

loc_804840A:

300

10.1.

10.

loc_804842E:
mov
movzx
test
jnz
mov
jmp

eax, [ebp+var_C]
eax, byte ptr [eax]
al, al
short loc_804843D
eax, [ebp+var_4]
short locret_8048453

add
jmp

[ebp+var_4], 1
short loc_8048444

loc_804843D:

loc_8048443:
nop
loc_8048444:
mov
movzx
test
jnz
mov

eax, [ebp+var_4]
eax, byte ptr [eax]
al, al
short loc_80483F4
eax, 0

locret_8048453:
leave
retn
endp

Keil (ARM) + -O3


PUSH
LDRB
CMP
POPEQ
B

{r4,lr}
r2,[r1,#0]
r2,#0
{r4,pc}
|L0.80|

LDRB
CMP
BEQ
LDRB
CMP
POPEQ
CMP
ADDEQ
ADDEQ
BEQ
B

r12,[r3,#0]
r12,#0
|L0.64|
r4,[r2,#0]
r4,#0
{r4,pc}
r12,r4
r3,r3,#1
r2,r2,#1
|L0.20|
|L0.76|

LDRB
CMP
POPEQ

r2,[r2,#0]
r2,#0
{r4,pc}

ADD

r0,r0,#1

LDRB
CMP
MOVNE
MOVNE
MOVEQ
BNE
POP

r2,[r0,#0]
r2,#0
r3,r0
r2,r1
r0,#0
|L0.20|
{r4,pc}

|L0.20|

|L0.64|

|L0.76|
|L0.80|

Keil (thumb) + -O3


PUSH
LDRB
CMP
BEQ
B

{r4,r5,lr}
r2,[r1,#0]
r2,#0
|L0.54|
|L0.46|

|L0.10|

301

10.1.
MOVS
MOVS
B

r3,r0
r2,r1
|L0.20|

ADDS
ADDS

r3,r3,#1
r2,r2,#1

LDRB
CMP
BEQ
LDRB
CMP
BEQ
CMP
BEQ
B

r4,[r3,#0]
r4,#0
|L0.38|
r5,[r2,#0]
r5,#0
|L0.54|
r4,r5
|L0.16|
|L0.44|

LDRB
CMP
BEQ

r2,[r2,#0]
r2,#0
|L0.54|

ADDS

r0,r0,#1

LDRB
CMP
BNE
MOVS

r2,[r0,#0]
r2,#0
|L0.10|
r0,#0

POP

{r4,r5,pc}

10.

|L0.16|

|L0.20|

|L0.38|

|L0.44|
|L0.46|

|L0.54|

10.1.5

1.5

, , , .
OpenWatcom The function is taken from OpenWatcom.
MSVC 2010 + /Ox
_DATA
SEGMENT
COMM
__v:DWORD
_DATA
ENDS
PUBLIC
__real@3e45798ee2308c3a
PUBLIC
__real@4147ffff80000000
PUBLIC
__real@4150017ec0000000
PUBLIC
_f
EXTRN
__fltused:DWORD
CONST
SEGMENT
__real@3e45798ee2308c3a DQ 03e45798ee2308c3ar
__real@4147ffff80000000 DQ 04147ffff80000000r
__real@4150017ec0000000 DQ 04150017ec0000000r
CONST
ENDS
_TEXT
SEGMENT
_v1$ = -16
; size = 8
_v2$ = -8
; size = 8
_f
PROC
sub
esp, 16
; 00000010H
fld
QWORD PTR __real@4150017ec0000000
fstp
QWORD PTR _v1$[esp+16]
fld
QWORD PTR __real@4147ffff80000000
fstp
QWORD PTR _v2$[esp+16]
fld
QWORD PTR _v1$[esp+16]
fld
QWORD PTR _v1$[esp+16]
fdiv
QWORD PTR _v2$[esp+16]
fmul
QWORD PTR _v2$[esp+16]
fsubp ST(1), ST(0)
fcomp QWORD PTR __real@3e45798ee2308c3a
fnstsw ax
test
ah, 65
; 00000041H
jne
SHORT $LN1@f
or
DWORD PTR __v, 1
$LN1@f:
add
esp, 16
; 00000010H
ret
0

; 1e-008
; 3.14573e+006
; 4.19584e+006

302

10.1.

10.

_f
ENDP
_TEXT
ENDS

10.1.6

1.6

MSVC 2010 + /Ox


PUBLIC
_f
; Function compile flags: /Ogtpy
_TEXT
SEGMENT
_k0$ = -12
; size = 4
_k3$ = -8
; size = 4
_k2$ = -4
; size = 4
_v$ = 8
; size = 4
_k1$ = 12
; size = 4
_k$ = 12
; size = 4
_f
PROC
sub
esp, 12
; 0000000cH
mov
ecx, DWORD PTR _v$[esp+8]
mov
eax, DWORD PTR [ecx]
mov
ecx, DWORD PTR [ecx+4]
push
ebx
push
esi
mov
esi, DWORD PTR _k$[esp+16]
push
edi
mov
edi, DWORD PTR [esi]
mov
DWORD PTR _k0$[esp+24], edi
mov
edi, DWORD PTR [esi+4]
mov
DWORD PTR _k1$[esp+20], edi
mov
edi, DWORD PTR [esi+8]
mov
esi, DWORD PTR [esi+12]
xor
edx, edx
mov
DWORD PTR _k2$[esp+24], edi
mov
DWORD PTR _k3$[esp+24], esi
lea
edi, DWORD PTR [edx+32]
$LL8@f:
mov
esi, ecx
shr
esi, 5
add
esi, DWORD PTR _k1$[esp+20]
mov
ebx, ecx
shl
ebx, 4
add
ebx, DWORD PTR _k0$[esp+24]
sub
edx, 1640531527
; 61c88647H
xor
esi, ebx
lea
ebx, DWORD PTR [edx+ecx]
xor
esi, ebx
add
eax, esi
mov
esi, eax
shr
esi, 5
add
esi, DWORD PTR _k3$[esp+24]
mov
ebx, eax
shl
ebx, 4
add
ebx, DWORD PTR _k2$[esp+24]
xor
esi, ebx
lea
ebx, DWORD PTR [edx+eax]
xor
esi, ebx
add
ecx, esi
dec
edi
jne
SHORT $LL8@f
mov
edx, DWORD PTR _v$[esp+20]
pop
edi
pop
esi
mov
DWORD PTR [edx], eax
mov
DWORD PTR [edx+4], ecx
pop
ebx
add
esp, 12
; 0000000cH
ret
0
_f
ENDP

Keil (ARM) + -O3

303

10.1.
PUSH
ADD
LDM
LDR
LDR
LDR
LDR
LDR
MOV
MOV

{r4-r10,lr}
r5,r1,#8
r5,{r5,r7}
r2,[r0,#4]
r3,[r0,#0]
r4,|L0.116|
r6,[r1,#4]
r8,[r1,#0]
r12,#0
r1,r12

ADD
ADD
ADD
EOR
ADD
EOR
ADD
ADD
ADD
EOR
ADD
EOR
ADD
CMP
ADD
STRCS
STRCS
BCC
POP

r12,r12,r4
r9,r8,r2,LSL #4
r10,r2,r12
r9,r9,r10
r10,r6,r2,LSR #5
r9,r9,r10
r3,r3,r9
r9,r5,r3,LSL #4
r10,r3,r12
r9,r9,r10
r10,r7,r3,LSR #5
r9,r9,r10
r1,r1,#1
r1,#0x20
r2,r2,r9
r2,[r0,#4]
r3,[r0,#0]
|L0.40|
{r4-r10,pc}

10.

|L0.40|

|L0.116|
DCD

0x9e3779b9

Keil (thumb) + -O3


PUSH
LDR
LDR
LDR
STR
MOVS
LDM
LDR
STR
LDR
MOVS
MOVS
MOV
MOV
STR

{r1-r7,lr}
r5,|L0.84|
r3,[r0,#0]
r2,[r0,#4]
r5,[sp,#8]
r6,r1
r6,{r6,r7}
r5,[r1,#8]
r6,[sp,#4]
r6,[r1,#0xc]
r4,#0
r1,r4
lr,r5
r12,r6
r7,[sp,#0]

LDR
LSLS
ADDS
LDR
LSRS
ADDS
ADDS
EORS
LDR
ADDS
ADDS
EORS
ADDS
LSLS
ADDS
ADD
EORS
LSRS
ADD
EORS
ADDS

r5,[sp,#8]
r6,r2,#4
r4,r4,r5
r5,[sp,#4]
r7,r2,#5
r5,r6,r5
r6,r2,r4
r5,r5,r6
r6,[sp,#0]
r1,r1,#1
r6,r7,r6
r5,r5,r6
r3,r5,r3
r5,r3,#4
r6,r3,r4
r5,r5,lr
r5,r5,r6
r6,r3,#5
r6,r6,r12
r5,r5,r6
r2,r5,r2

|L0.30|

304

10.1.

10.

CMP
BCC
STR
STR
POP

r1,#0x20
|L0.30|
r3,[r0,#0]
r2,[r0,#4]
{r1-r7,pc}

DCD

0x9e3779b9

|L0.84|

10.1.7

1.7

Linux 2.6.
MSVC 2010 + /Ox
_table
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db

db
010h,
008h,
018h,
004h,
014h,
00ch,
01ch,
002h,
012h,
00ah,
01ah,
006h,
016h,
00eh,
01eh,
001h,
011h,
009h,
019h,
005h,
015h,
00dh,
01dh,
003h,
013h,
00bh,
01bh,
007h,
017h,
00fh,
01fh,

000h,
090h,
088h,
098h,
084h,
094h,
08ch,
09ch,
082h,
092h,
08ah,
09ah,
086h,
096h,
08eh,
09eh,
081h,
091h,
089h,
099h,
085h,
095h,
08dh,
09dh,
083h,
093h,
08bh,
09bh,
087h,
097h,
08fh,
09fh,

080h,
050h,
048h,
058h,
044h,
054h,
04ch,
05ch,
042h,
052h,
04ah,
05ah,
046h,
056h,
04eh,
05eh,
041h,
051h,
049h,
059h,
045h,
055h,
04dh,
05dh,
043h,
053h,
04bh,
05bh,
047h,
057h,
04fh,
05fh,

040h,
0d0h,
0c8h,
0d8h,
0c4h,
0d4h,
0cch,
0dch,
0c2h,
0d2h,
0cah,
0dah,
0c6h,
0d6h,
0ceh,
0deh,
0c1h,
0d1h,
0c9h,
0d9h,
0c5h,
0d5h,
0cdh,
0ddh,
0c3h,
0d3h,
0cbh,
0dbh,
0c7h,
0d7h,
0cfh,
0dfh,

proc near

arg_0

= dword ptr
mov
movzx
movzx
mov
shr
movzx
movzx
shl
movzx
or
shr
movzx
movzx
shr
movzx
movzx
shl
movzx
shl
or

0c0h,
030h,
028h,
038h,
024h,
034h,
02ch,
03ch,
022h,
032h,
02ah,
03ah,
026h,
036h,
02eh,
03eh,
021h,
031h,
029h,
039h,
025h,
035h,
02dh,
03dh,
023h,
033h,
02bh,
03bh,
027h,
037h,
02fh,
03fh,

020h,
0b0h,
0a8h,
0b8h,
0a4h,
0b4h,
0ach,
0bch,
0a2h,
0b2h,
0aah,
0bah,
0a6h,
0b6h,
0aeh,
0beh,
0a1h,
0b1h,
0a9h,
0b9h,
0a5h,
0b5h,
0adh,
0bdh,
0a3h,
0b3h,
0abh,
0bbh,
0a7h,
0b7h,
0afh,
0bfh,

0a0h,
070h,
068h,
078h,
064h,
074h,
06ch,
07ch,
062h,
072h,
06ah,
07ah,
066h,
076h,
06eh,
07eh,
061h,
071h,
069h,
079h,
065h,
075h,
06dh,
07dh,
063h,
073h,
06bh,
07bh,
067h,
077h,
06fh,
07fh,

060h, 0e0h
0f0h
0e8h
0f8h
0e4h
0f4h
0ech
0fch
0e2h
0f2h
0eah
0fah
0e6h
0f6h
0eeh
0feh
0e1h
0f1h
0e9h
0f9h
0e5h
0f5h
0edh
0fdh
0e3h
0f3h
0ebh
0fbh
0e7h
0f7h
0efh
0ffh

edx, [esp+arg_0]
eax, dl
eax, _table[eax]
ecx, edx
edx, 8
edx, dl
edx, _table[edx]
ax, 8
eax, ax
eax, edx
ecx, 10h
edx, cl
edx, _table[edx]
ecx, 8
ecx, cl
ecx, _table[ecx]
dx, 8
edx, dx
eax, 10h
edx, ecx

305

10.1.
or
retn
endp

10.
eax, edx

Keil (ARM) + -O3


f2 PROC
LDR
LDRB
AND
LDRB
ORR
BX
ENDP

r1,|L0.76|
r2,[r1,r0,LSR #8]
r0,r0,#0xff
r0,[r1,r0]
r0,r2,r0,LSL #8
lr

MOV
LSR
PUSH
BL
MOV
LSL
LSR
BL
ORR
POP
ENDP

r3,r0
r0,r0,#16
{lr}
f2
r12,r0
r0,r3,#16
r0,r0,#16
f2
r0,r12,r0,LSL #16
{pc}

DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB

0x00,0x80,0x40,0xc0
0x20,0xa0,0x60,0xe0
0x10,0x90,0x50,0xd0
0x30,0xb0,0x70,0xf0
0x08,0x88,0x48,0xc8
0x28,0xa8,0x68,0xe8
0x18,0x98,0x58,0xd8
0x38,0xb8,0x78,0xf8
0x04,0x84,0x44,0xc4
0x24,0xa4,0x64,0xe4
0x14,0x94,0x54,0xd4
0x34,0xb4,0x74,0xf4
0x0c,0x8c,0x4c,0xcc
0x2c,0xac,0x6c,0xec
0x1c,0x9c,0x5c,0xdc
0x3c,0xbc,0x7c,0xfc
0x02,0x82,0x42,0xc2
0x22,0xa2,0x62,0xe2
0x12,0x92,0x52,0xd2
0x32,0xb2,0x72,0xf2
0x0a,0x8a,0x4a,0xca
0x2a,0xaa,0x6a,0xea
0x1a,0x9a,0x5a,0xda
0x3a,0xba,0x7a,0xfa
0x06,0x86,0x46,0xc6
0x26,0xa6,0x66,0xe6
0x16,0x96,0x56,0xd6
0x36,0xb6,0x76,0xf6
0x0e,0x8e,0x4e,0xce
0x2e,0xae,0x6e,0xee
0x1e,0x9e,0x5e,0xde
0x3e,0xbe,0x7e,0xfe
0x01,0x81,0x41,0xc1
0x21,0xa1,0x61,0xe1
0x11,0x91,0x51,0xd1
0x31,0xb1,0x71,0xf1
0x09,0x89,0x49,0xc9
0x29,0xa9,0x69,0xe9
0x19,0x99,0x59,0xd9
0x39,0xb9,0x79,0xf9
0x05,0x85,0x45,0xc5
0x25,0xa5,0x65,0xe5
0x15,0x95,0x55,0xd5
0x35,0xb5,0x75,0xf5
0x0d,0x8d,0x4d,0xcd

f3 PROC

|L0.76|

306

10.1.
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB

10.

0x2d,0xad,0x6d,0xed
0x1d,0x9d,0x5d,0xdd
0x3d,0xbd,0x7d,0xfd
0x03,0x83,0x43,0xc3
0x23,0xa3,0x63,0xe3
0x13,0x93,0x53,0xd3
0x33,0xb3,0x73,0xf3
0x0b,0x8b,0x4b,0xcb
0x2b,0xab,0x6b,0xeb
0x1b,0x9b,0x5b,0xdb
0x3b,0xbb,0x7b,0xfb
0x07,0x87,0x47,0xc7
0x27,0xa7,0x67,0xe7
0x17,0x97,0x57,0xd7
0x37,0xb7,0x77,0xf7
0x0f,0x8f,0x4f,0xcf
0x2f,0xaf,0x6f,0xef
0x1f,0x9f,0x5f,0xdf
0x3f,0xbf,0x7f,0xff

Keil (thumb) + -O3


f2 PROC
LDR
LSLS
LSRS
LDRB
LSLS
LSRS
LDRB
ORRS
BX
ENDP

r1,|L0.48|
r2,r0,#24
r2,r2,#24
r2,[r1,r2]
r2,r2,#8
r0,r0,#8
r0,[r1,r0]
r0,r0,r2
lr

MOVS
LSLS
PUSH
LSRS
BL
LSLS
LSRS
BL
ORRS
POP
ENDP

r3,r0
r0,r0,#16
{r4,lr}
r0,r0,#16
f2
r4,r0,#16
r0,r3,#16
f2
r0,r0,r4
{r4,pc}

DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB

0x00,0x80,0x40,0xc0
0x20,0xa0,0x60,0xe0
0x10,0x90,0x50,0xd0
0x30,0xb0,0x70,0xf0
0x08,0x88,0x48,0xc8
0x28,0xa8,0x68,0xe8
0x18,0x98,0x58,0xd8
0x38,0xb8,0x78,0xf8
0x04,0x84,0x44,0xc4
0x24,0xa4,0x64,0xe4
0x14,0x94,0x54,0xd4
0x34,0xb4,0x74,0xf4
0x0c,0x8c,0x4c,0xcc
0x2c,0xac,0x6c,0xec
0x1c,0x9c,0x5c,0xdc
0x3c,0xbc,0x7c,0xfc
0x02,0x82,0x42,0xc2
0x22,0xa2,0x62,0xe2
0x12,0x92,0x52,0xd2
0x32,0xb2,0x72,0xf2
0x0a,0x8a,0x4a,0xca
0x2a,0xaa,0x6a,0xea
0x1a,0x9a,0x5a,0xda
0x3a,0xba,0x7a,0xfa
0x06,0x86,0x46,0xc6
0x26,0xa6,0x66,0xe6

f3 PROC

|L0.48|

307

10.1.
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB
DCB

10.1.8

10.

0x16,0x96,0x56,0xd6
0x36,0xb6,0x76,0xf6
0x0e,0x8e,0x4e,0xce
0x2e,0xae,0x6e,0xee
0x1e,0x9e,0x5e,0xde
0x3e,0xbe,0x7e,0xfe
0x01,0x81,0x41,0xc1
0x21,0xa1,0x61,0xe1
0x11,0x91,0x51,0xd1
0x31,0xb1,0x71,0xf1
0x09,0x89,0x49,0xc9
0x29,0xa9,0x69,0xe9
0x19,0x99,0x59,0xd9
0x39,0xb9,0x79,0xf9
0x05,0x85,0x45,0xc5
0x25,0xa5,0x65,0xe5
0x15,0x95,0x55,0xd5
0x35,0xb5,0x75,0xf5
0x0d,0x8d,0x4d,0xcd
0x2d,0xad,0x6d,0xed
0x1d,0x9d,0x5d,0xdd
0x3d,0xbd,0x7d,0xfd
0x03,0x83,0x43,0xc3
0x23,0xa3,0x63,0xe3
0x13,0x93,0x53,0xd3
0x33,0xb3,0x73,0xf3
0x0b,0x8b,0x4b,0xcb
0x2b,0xab,0x6b,0xeb
0x1b,0x9b,0x5b,0xdb
0x3b,0xbb,0x7b,0xfb
0x07,0x87,0x47,0xc7
0x27,0xa7,0x67,0xe7
0x17,0x97,0x57,0xd7
0x37,0xb7,0x77,0xf7
0x0f,0x8f,0x4f,0xcf
0x2f,0xaf,0x6f,0xef
0x1f,0x9f,0x5f,0xdf
0x3f,0xbf,0x7f,0xff

1.8

MSVC 2010 + /O1


(/O1: ).
_a$ = 8
; size = 4
_b$ = 12
; size = 4
_c$ = 16
; size = 4
?s@@YAXPAN00@Z PROC
; s, COMDAT
mov
eax, DWORD PTR _b$[esp-4]
mov
ecx, DWORD PTR _a$[esp-4]
mov
edx, DWORD PTR _c$[esp-4]
push
esi
push
edi
sub
ecx, eax
sub
edx, eax
mov
edi, 200
; 000000c8H
$LL6@s:
push
100
; 00000064H
pop
esi
$LL3@s:
fld
QWORD PTR [ecx+eax]
fadd
QWORD PTR [eax]
fstp
QWORD PTR [edx+eax]
add
eax, 8
dec
esi
jne
SHORT $LL3@s
dec
edi
jne
SHORT $LL6@s
pop
edi
pop
esi
ret
0
?s@@YAXPAN00@Z ENDP
; s

308

10.1.
Keil (ARM) + -O3
PUSH
MOV
MOV
MOV
MOV

{r4-r12,lr}
r9,r2
r10,r1
r11,r0
r5,#0

ADD
ADD
MOV
ADD
ADD
ADD

r0,r5,r5,LSL #3
r0,r0,r5,LSL #4
r4,#0
r8,r10,r0,LSL #5
r7,r11,r0,LSL #5
r6,r9,r0,LSL #5

ADD
LDM
ADD
LDM
BL
ADD
ADD
STM
CMP
BLT
ADD
CMP
BLT
POP

r0,r8,r4,LSL #3
r0,{r2,r3}
r1,r7,r4,LSL #3
r1,{r0,r1}
__aeabi_dadd
r2,r6,r4,LSL #3
r4,r4,#1
r2,{r0,r1}
r4,#0x64
|L0.44|
r5,r5,#1
r5,#0xc8
|L0.20|
{r4-r12,pc}

10.

|L0.20|

|L0.44|

Keil (thumb) + -O3


PUSH
MOVS
SUB

{r0-r2,r4-r7,lr}
r4,#0
sp,sp,#8

MOVS
MOVS
LSLS
MULS
LDR
LDR
ADDS
STR
LDR
MOVS
ADDS
ADDS
STR

r1,#0x19
r0,r4
r1,r1,#5
r0,r1,r0
r2,[sp,#8]
r1,[sp,#0xc]
r2,r0,r2
r2,[sp,#0]
r2,[sp,#0x10]
r5,#0
r7,r0,r2
r0,r0,r1
r0,[sp,#4]

LSLS
ADDS
LDM
LDR
ADDS
LDM
BL
ADDS
ADDS
STM
CMP
BGE
LDR
B

r6,r5,#3
r0,r0,r6
r0!,{r2,r3}
r0,[sp,#0]
r1,r0,r6
r1,{r0,r1}
__aeabi_dadd
r2,r7,r6
r5,r5,#1
r2!,{r0,r1}
r5,#0x64
|L0.62|
r0,[sp,#4]
|L0.32|

ADDS
CMP
BLT
ADD
POP

r4,r4,#1
r4,#0xc8
|L0.6|
sp,sp,#0x14
{r4-r7,pc}

|L0.6|

|L0.32|

|L0.62|

309

10.1.

10.1.9

10.

1.9

MSVC 2010 + /O1


(/O1: ).
tv315 = -8
; size = 4
tv291 = -4
; size = 4
_a$ = 8
; size = 4
_b$ = 12
; size = 4
_c$ = 16
; size = 4
?m@@YAXPAN00@Z PROC
; m, COMDAT
push
ebp
mov
ebp, esp
push
ecx
push
ecx
mov
edx, DWORD PTR _a$[ebp]
push
ebx
mov
ebx, DWORD PTR _c$[ebp]
push
esi
mov
esi, DWORD PTR _b$[ebp]
sub
edx, esi
push
edi
sub
esi, ebx
mov
DWORD PTR tv315[ebp], 100 ; 00000064H
$LL9@m:
mov
eax, ebx
mov
DWORD PTR tv291[ebp], 300 ; 0000012cH
$LL6@m:
fldz
lea
ecx, DWORD PTR [esi+eax]
fstp
QWORD PTR [eax]
mov
edi, 200
; 000000c8H
$LL3@m:
dec
edi
fld
QWORD PTR [ecx+edx]
fmul
QWORD PTR [ecx]
fadd
QWORD PTR [eax]
fstp
QWORD PTR [eax]
jne
HORT $LL3@m
add
eax, 8
dec
DWORD PTR tv291[ebp]
jne
SHORT $LL6@m
add
ebx, 800
; 00000320H
dec
DWORD PTR tv315[ebp]
jne
SHORT $LL9@m
pop
edi
pop
esi
pop
ebx
leave
ret
0
?m@@YAXPAN00@Z ENDP
; m

Keil (ARM) + -O3


PUSH
SUB
MOV

{r0-r2,r4-r11,lr}
sp,sp,#8
r5,#0

LDR
ADD
ADD
ADD
STR
LDR
MOV
ADD
LDR
ADD

r1,[sp,#0xc]
r0,r5,r5,LSL #3
r0,r0,r5,LSL #4
r1,r1,r0,LSL #5
r1,[sp,#0]
r1,[sp,#8]
r4,#0
r11,r1,r0,LSL #5
r1,[sp,#0x10]
r10,r1,r0,LSL #5

MOV
MOV
ADD

r0,#0
r1,r0
r7,r10,r4,LSL #3

|L0.12|

|L0.52|

310

10.1.
STM
MOV
LDR
ADD
ADD

r7,{r0,r1}
r6,r0
r0,[sp,#0]
r8,r11,r4,LSL #3
r9,r0,r4,LSL #3

LDM
LDM
BL
LDM
BL
ADD
STM
CMP
BLT
ADD
CMP
BLT
ADD
CMP
BLT
ADD
POP

r9,{r2,r3}
r8,{r0,r1}
__aeabi_dmul
r7,{r2,r3}
__aeabi_dadd
r6,r6,#1
r7,{r0,r1}
r6,#0xc8
|L0.84|
r4,r4,#1
r4,#0x12c
|L0.52|
r5,r5,#1
r5,#0x64
|L0.12|
sp,sp,#0x14
{r4-r11,pc}

10.

|L0.84|

Keil (thumb) + -O3


PUSH
MOVS
SUB
STR

{r0-r2,r4-r7,lr}
r0,#0
sp,sp,#0x10
r0,[sp,#0]

MOVS
LSLS
MULS
LDR
LDR
ADDS
STR
LDR
MOVS
ADDS
ADDS
STR

r1,#0x19
r1,r1,#5
r0,r1,r0
r2,[sp,#0x10]
r1,[sp,#0x14]
r2,r0,r2
r2,[sp,#4]
r2,[sp,#0x18]
r5,#0
r7,r0,r2
r0,r0,r1
r0,[sp,#8]

LSLS
MOVS
ADDS
STR
MOVS
STR

r4,r5,#3
r0,#0
r2,r7,r4
r0,[r2,#0]
r6,r0
r0,[r2,#4]

LDR
ADDS
LDM
LDR
ADDS
LDM
BL
ADDS
LDM
BL
ADDS
ADDS
STM
CMP
BLT
MOVS
ADDS
ADDS
CMP
BLT
LDR
ADDS
CMP

r0,[sp,#8]
r0,r0,r4
r0!,{r2,r3}
r0,[sp,#4]
r1,r0,r4
r1,{r0,r1}
__aeabi_dmul
r3,r7,r4
r3,{r2,r3}
__aeabi_dadd
r2,r7,r4
r6,r6,#1
r2!,{r0,r1}
r6,#0xc8
|L0.44|
r0,#0xff
r5,r5,#1
r0,r0,#0x2d
r5,r0
|L0.32|
r0,[sp,#0]
r0,r0,#1
r0,#0x64

|L0.8|

|L0.32|

|L0.44|

311

10.2.
STR
BLT
ADD
POP

10.1.10

10.

r0,[sp,#0]
|L0.8|
sp,sp,#0x1c
{r4-r7,pc}

1.10

, . ?
MSVC (/Ox)?
#include <stdio.h>
int main()
{
printf ("%d\n");
return 0;
};

10.1.11

1.11

, Windows Task Manager /


:

. 10.1: Windows Task Manager

10.2

10.2.1

2.1

, . glibc 2.11.1.
GCC 4.4.1 -Os ( ).
312

10.2.
10.
IDA 4.9 ELF- GCC .
IDA , .elf .idb , .idb
IDA 4.9:
http://yurichev.com/RE-exercises/middle/1/
f

proc near

var_150
var_14C
var_13C
var_138
var_134
var_130
var_128
var_124
var_120
var_11C
var_118
var_114
var_110
var_C
arg_0
arg_4
arg_8
arg_C
arg_10

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword

ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr

-150h
-14Ch
-13Ch
-138h
-134h
-130h
-128h
-124h
-120h
-11Ch
-118h
-114h
-110h
-0Ch
8
0Ch
10h
14h
18h

push
mov
push
push
push
sub
mov
cmp
jz
cmp
lea
mov
jbe
mov
mov
mov
lea
neg
mov
mov
dec
imul
add
mov
mov
mov
lea
mov
mov

ebp
ebp, esp
edi
esi
ebx
esp, 14Ch
ebx, [ebp+arg_8]
[ebp+arg_4], 0
loc_804877D
[ebp+arg_4], 4
eax, ds:0[ebx*4]
[ebp+var_130], eax
loc_804864C
eax, [ebp+arg_4]
ecx, ebx
esi, [ebp+arg_0]
edx, [ebp+var_110]
ecx
[ebp+var_118], 0
[ebp+var_114], 0
eax
eax, ebx
eax, [ebp+arg_0]
[ebp+var_11C], edx
[ebp+var_134], ecx
[ebp+var_124], eax
eax, [ebp+var_118]
[ebp+var_14C], eax
[ebp+var_120], ebx

mov
xor
push
push
sub
div
push
shr
imul
lea
push
mov
call
add
mov
test
jns
xor

; CODE XREF: f+28C


eax, [ebp+var_124]
edx, edx
edi
[ebp+arg_10]
eax, esi
[ebp+var_120]
esi
eax, 1
eax, [ebp+var_120]
edx, [esi+eax]
edx
[ebp+var_138], edx
[ebp+arg_C]
esp, 10h
edx, [ebp+var_138]
eax, eax
short loc_8048482
eax, eax

loc_8048433:

313

10.2.
loc_804846D:

10.

mov
mov
mov
mov
inc
cmp
jnz

; CODE XREF: f+CC


cl, [edx+eax]
bl, [esi+eax]
[edx+eax], bl
[esi+eax], cl
eax
[ebp+var_120], eax
short loc_804846D

push
push
mov
push
push
call
mov
add
test
jns
mov
xor

; CODE XREF: f+B5


ebx
[ebp+arg_10]
[ebp+var_138], edx
edx
[ebp+var_124]
[ebp+arg_C]
edx, [ebp+var_138]
esp, 10h
eax, eax
short loc_80484F6
ecx, [ebp+var_124]
eax, eax

movzx
mov
mov
mov
mov
inc
cmp
jnz
push
push
mov
push
push
call
add
mov
test
jns
xor

; CODE XREF: f+10D


edi, byte ptr [edx+eax]
bl, [ecx+eax]
[edx+eax], bl
ebx, edi
[ecx+eax], bl
eax
[ebp+var_120], eax
short loc_80484AB
ecx
[ebp+arg_10]
[ebp+var_138], edx
esi
edx
[ebp+arg_C]
esp, 10h
edx, [ebp+var_138]
eax, eax
short loc_80484F6
eax, eax

mov
mov
mov
mov
inc
cmp
jnz

; CODE XREF: f+140


cl, [edx+eax]
bl, [esi+eax]
[edx+eax], bl
[esi+eax], cl
eax
[ebp+var_120], eax
short loc_80484E1

loc_8048482:

loc_80484AB:

loc_80484E1:

loc_80484F6:

; CODE XREF: f+ED


; f+129
mov
eax, [ebp+var_120]
mov
edi, [ebp+var_124]
add
edi, [ebp+var_134]
lea
ebx, [esi+eax]
jmp
short loc_8048513
; --------------------------------------------------------------------------loc_804850D:
add
loc_8048513:

; CODE XREF: f+17B


ebx, [ebp+var_120]
; CODE XREF: f+157
; f+1F9

push
push
mov
push
push
call
add
mov

eax
[ebp+arg_10]
[ebp+var_138], edx
edx
ebx
[ebp+arg_C]
esp, 10h
edx, [ebp+var_138]

314

10.2.

10.

test
eax, eax
jns
short loc_8048537
jmp
short loc_804850D
; --------------------------------------------------------------------------loc_8048531:
add

; CODE XREF: f+19D


edi, [ebp+var_134]

push
push
mov
push
push
call
add
mov
test
js
cmp
jnb
xor
mov

; CODE XREF: f+179


ecx
[ebp+arg_10]
[ebp+var_138], edx
edi
edx
[ebp+arg_C]
esp, 10h
edx, [ebp+var_138]
eax, eax
short loc_8048531
ebx, edi
short loc_8048596
eax, eax
[ebp+var_128], edx

loc_8048537:

loc_804855F:

; CODE XREF: f+1BE


mov
cl, [ebx+eax]
mov
dl, [edi+eax]
mov
[ebx+eax], dl
mov
[edi+eax], cl
inc
eax
cmp
[ebp+var_120], eax
jnz
short loc_804855F
mov
edx, [ebp+var_128]
cmp
edx, ebx
jnz
short loc_8048582
mov
edx, edi
jmp
short loc_8048588
; --------------------------------------------------------------------------loc_8048582:
cmp
jnz
mov

; CODE XREF: f+1C8


edx, edi
short loc_8048588
edx, ebx

loc_8048588:

; CODE XREF: f+1CC


; f+1D0
add
ebx, [ebp+var_120]
add
edi, [ebp+var_134]
jmp
short loc_80485AB
; --------------------------------------------------------------------------loc_8048596:

; CODE XREF: f+1A1


jnz
short loc_80485AB
mov
ecx, [ebp+var_134]
mov
eax, [ebp+var_120]
lea
edi, [ebx+ecx]
add
ebx, eax
jmp
short loc_80485B3
; --------------------------------------------------------------------------loc_80485AB:

; CODE XREF: f+1E0


; f:loc_8048596
cmp
jbe

ebx, edi
loc_8048513

mov
sub
cmp
ja
mov
mov
sub
cmp
ja
sub

; CODE XREF: f+1F5


eax, edi
eax, esi
eax, [ebp+var_130]
short loc_80485EB
eax, [ebp+var_124]
esi, ebx
eax, ebx
eax, [ebp+var_130]
short loc_8048634
[ebp+var_11C], 8

loc_80485B3:

315

10.2.

10.

mov
edx, [ebp+var_11C]
mov
ecx, [edx+4]
mov
esi, [edx]
mov
[ebp+var_124], ecx
jmp
short loc_8048634
; --------------------------------------------------------------------------loc_80485EB:

; CODE XREF: f+209


mov
edx, [ebp+var_124]
sub
edx, ebx
cmp
edx, [ebp+var_130]
jbe
short loc_804862E
cmp
eax, edx
mov
edx, [ebp+var_11C]
lea
eax, [edx+8]
jle
short loc_8048617
mov
[edx], esi
mov
esi, ebx
mov
[edx+4], edi
mov
[ebp+var_11C], eax
jmp
short loc_8048634
; --------------------------------------------------------------------------loc_8048617:
mov
mov
mov
mov
mov

; CODE XREF: f+252


ecx, [ebp+var_11C]
[ebp+var_11C], eax
[ecx], ebx
ebx, [ebp+var_124]
[ecx+4], ebx

mov

; CODE XREF: f+245


[ebp+var_124], edi

mov
cmp
ja
mov

; CODE XREF: f+21B


; f+235 ...
eax, [ebp+var_14C]
[ebp+var_11C], eax
loc_8048433
ebx, [ebp+var_120]

mov
mov
add
dec
imul
add
cmp
mov
jbe
mov

; CODE XREF: f+2A


eax, [ebp+arg_4]
ecx, [ebp+arg_0]
ecx, [ebp+var_130]
eax
eax, ebx
eax, [ebp+arg_0]
ecx, eax
[ebp+var_120], eax
short loc_804866B
ecx, eax

loc_804862E:

loc_8048634:

loc_804864C:

loc_804866B:

; CODE XREF: f+2B3


mov
esi, [ebp+arg_0]
mov
edi, [ebp+arg_0]
add
esi, ebx
mov
edx, esi
jmp
short loc_80486A3
; --------------------------------------------------------------------------loc_8048677:
push
push
mov
mov
push
push
call
add
mov
mov
test
jns
mov
loc_80486A1:

; CODE XREF: f+2F1


eax
[ebp+arg_10]
[ebp+var_138], edx
[ebp+var_13C], ecx
edi
edx
[ebp+arg_C]
esp, 10h
edx, [ebp+var_138]
ecx, [ebp+var_13C]
eax, eax
short loc_80486A1
edi, edx
; CODE XREF: f+2E9

316

10.2.

10.

add

edx, ebx

cmp
jbe
cmp
jz
xor

; CODE XREF: f+2C1


edx, ecx
short loc_8048677
edi, [ebp+arg_0]
loc_8048762
eax, eax

loc_80486A3:

loc_80486B2:

; CODE XREF: f+313


mov
ecx, [ebp+arg_0]
mov
dl, [edi+eax]
mov
cl, [ecx+eax]
mov
[edi+eax], cl
mov
ecx, [ebp+arg_0]
mov
[ecx+eax], dl
inc
eax
cmp
ebx, eax
jnz
short loc_80486B2
jmp
loc_8048762
; --------------------------------------------------------------------------loc_80486CE:

; CODE XREF: f+3C3


lea
edx, [esi+edi]
jmp
short loc_80486D5
; --------------------------------------------------------------------------loc_80486D3:

; CODE XREF: f+33B


add

edx, edi

loc_80486D5:

; CODE XREF: f+31D


push
eax
push
[ebp+arg_10]
mov
[ebp+var_138], edx
push
edx
push
esi
call
[ebp+arg_C]
add
esp, 10h
mov
edx, [ebp+var_138]
test
eax, eax
js
short loc_80486D3
add
edx, ebx
cmp
edx, esi
mov
[ebp+var_124], edx
jz
short loc_804876F
mov
edx, [ebp+var_134]
lea
eax, [esi+ebx]
add
edx, eax
mov
[ebp+var_11C], edx
jmp
short loc_804875B
; --------------------------------------------------------------------------loc_8048710:

; CODE XREF: f+3AA


mov
cl, [eax]
mov
edx, [ebp+var_11C]
mov
[ebp+var_150], eax
mov
byte ptr [ebp+var_130], cl
mov
ecx, eax
jmp
short loc_8048733
; --------------------------------------------------------------------------loc_8048728:
mov
mov
mov

; CODE XREF: f+391


al, [edx+ebx]
[ecx], al
ecx, [ebp+var_128]

mov
add
mov
sub
cmp
jbe
mov
mov
mov

; CODE XREF: f+372


[ebp+var_128], edx
edx, edi
eax, edx
eax, edi
[ebp+var_124], eax
short loc_8048728
dl, byte ptr [ebp+var_130]
eax, [ebp+var_150]
[ecx], dl

loc_8048733:

317

10.2.
dec

10.

[ebp+var_11C]

loc_804875B:

; CODE XREF: f+35A


dec
eax
cmp
eax, esi
jnb
short loc_8048710
jmp
short loc_804876F
; --------------------------------------------------------------------------loc_8048762:

; CODE XREF: f+2F6


; f+315
mov
neg
lea
mov

edi, ebx
edi
ecx, [edi-1]
[ebp+var_134], ecx

loc_804876F:

; CODE XREF: f+347


; f+3AC
add
cmp
jbe

esi, ebx
esi, [ebp+var_120]
loc_80486CE

lea
pop
pop
pop
pop
retn
endp

esp, [ebp-0Ch]
ebx
esi
edi
ebp

loc_804877D:

10.2.2

; CODE XREF: f+13

2.2

, .
.
Windows x86
Linux x86
MacOSX (x64)

10.2.3

2.3

, . , , - . , .
Windows x86
Linux x86
MacOSX (x64)

10.2.4

2.4

, . ,
. . , , . - .
.
Windows x86

318

10.3. CRACKME / KEYGENME

10.2.5

10.

2.5

.
.
:
() tracer 6.0.1 , .
() ,
, .
Windows x86
Linux x86
MacOSX (x64)

10.2.6

2.6

-, , CGI1 ,
. 4 .
.
Windows x86
Linux x86
MacOSX (x64)

10.2.7

2.7

tracer 6.0.1 win32-, ,


Windows MineSweeper.
: [26] MineSweeper.

10.3

crackme / keygenme

keygenme:
http://crackmes.de/users/yonkie/

Common Gateway Interface

319

11.

11


11.1

11.1.1

1.1

: toupper().
:
char toupper ( char c )
{
if( c >= a && c <= z ) {
c = c - a + A;
}
return( c );
}

11.1.2

1.2

: atoi()
:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int atoi ( const *p )
{
int i;
char s;

/* convert ASCII string to integer */

while( isspace ( *p ) )
++p;
s = *p;
if( s == + || s == - )
++p;
i = 0;
while( isdigit(*p) ) {
i = i * 10 + *p - 0;
++p;
}
if( s == - )
i = - i;
return( i );
}

11.1.3

1.3

: srand() / rand().
:

320

11.1.

11.

static unsigned int v;


void srand (unsigned int s)
{
v = s;
}
int rand ()
{
return( ((v = v * 214013L
+ 2531011L) >> 16) & 0x7fff );
}

11.1.4

1.4

: strstr().
:
char * strstr (
const char * str1,
const char * str2
)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}

11.1.5

1.5

#1: __v .
#2: startup- main().
: FDIV- Pentium1 .
:
unsigned _v; // _v
enum e {
PROB_P5_DIV = 0x0001
};
void f( void ) // __verify_pentium_fdiv_bug
{
/*
Verify we have got the Pentium FDIV problem.
The volatiles are to scare the optimizer away.
*/
volatile double
v1
= 4195835;
1

http://en.wikipedia.org/wiki/Pentium_FDIV_bug

321

11.1.
volatile double

11.
v2

= 3145727;

if( (v1 - (v1/v2)*v2) > 1.0e-8 ) {


_v |= PROB_P5_DIV;
}
}

11.1.6

1.6

: , .
: TEA2 .
( http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm):
void f (unsigned int* v, unsigned int* k) {
unsigned int v0=v[0], v1=v[1], sum=0, i;
/* set up */
unsigned int delta=0x9e3779b9;
/* a key schedule constant */
unsigned int k0=k[0], k1=k[1], k2=k[2], k3=k[3];
/* cache key */
for (i=0; i < 32; i++) {
/* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
/* end cycle */
v[0]=v0; v[1]=v1;
}

11.1.7

1.7

: . ,
.
: 32- . lib/bitrev.c
Linux.
:
const unsigned char
0x00, 0x80,
0x10, 0x90,
0x08, 0x88,
0x18, 0x98,
0x04, 0x84,
0x14, 0x94,
0x0c, 0x8c,
0x1c, 0x9c,
0x02, 0x82,
0x12, 0x92,
0x0a, 0x8a,
0x1a, 0x9a,
0x06, 0x86,
0x16, 0x96,
0x0e, 0x8e,
0x1e, 0x9e,
0x01, 0x81,
0x11, 0x91,
0x09, 0x89,
0x19, 0x99,
0x05, 0x85,
0x15, 0x95,
0x0d, 0x8d,
0x1d, 0x9d,
0x03, 0x83,
0x13, 0x93,
0x0b, 0x8b,
0x1b, 0x9b,
0x07, 0x87,
0x17, 0x97,
0x0f, 0x8f,
0x1f, 0x9f,
};
2

byte_rev_table[256] = {
0x40, 0xc0, 0x20, 0xa0,
0x50, 0xd0, 0x30, 0xb0,
0x48, 0xc8, 0x28, 0xa8,
0x58, 0xd8, 0x38, 0xb8,
0x44, 0xc4, 0x24, 0xa4,
0x54, 0xd4, 0x34, 0xb4,
0x4c, 0xcc, 0x2c, 0xac,
0x5c, 0xdc, 0x3c, 0xbc,
0x42, 0xc2, 0x22, 0xa2,
0x52, 0xd2, 0x32, 0xb2,
0x4a, 0xca, 0x2a, 0xaa,
0x5a, 0xda, 0x3a, 0xba,
0x46, 0xc6, 0x26, 0xa6,
0x56, 0xd6, 0x36, 0xb6,
0x4e, 0xce, 0x2e, 0xae,
0x5e, 0xde, 0x3e, 0xbe,
0x41, 0xc1, 0x21, 0xa1,
0x51, 0xd1, 0x31, 0xb1,
0x49, 0xc9, 0x29, 0xa9,
0x59, 0xd9, 0x39, 0xb9,
0x45, 0xc5, 0x25, 0xa5,
0x55, 0xd5, 0x35, 0xb5,
0x4d, 0xcd, 0x2d, 0xad,
0x5d, 0xdd, 0x3d, 0xbd,
0x43, 0xc3, 0x23, 0xa3,
0x53, 0xd3, 0x33, 0xb3,
0x4b, 0xcb, 0x2b, 0xab,
0x5b, 0xdb, 0x3b, 0xbb,
0x47, 0xc7, 0x27, 0xa7,
0x57, 0xd7, 0x37, 0xb7,
0x4f, 0xcf, 0x2f, 0xaf,
0x5f, 0xdf, 0x3f, 0xbf,

0x60,
0x70,
0x68,
0x78,
0x64,
0x74,
0x6c,
0x7c,
0x62,
0x72,
0x6a,
0x7a,
0x66,
0x76,
0x6e,
0x7e,
0x61,
0x71,
0x69,
0x79,
0x65,
0x75,
0x6d,
0x7d,
0x63,
0x73,
0x6b,
0x7b,
0x67,
0x77,
0x6f,
0x7f,

0xe0,
0xf0,
0xe8,
0xf8,
0xe4,
0xf4,
0xec,
0xfc,
0xe2,
0xf2,
0xea,
0xfa,
0xe6,
0xf6,
0xee,
0xfe,
0xe1,
0xf1,
0xe9,
0xf9,
0xe5,
0xf5,
0xed,
0xfd,
0xe3,
0xf3,
0xeb,
0xfb,
0xe7,
0xf7,
0xef,
0xff,

Tiny Encryption Algorithm

322

11.1.

11.

unsigned char bitrev8(unsigned char byte)


{
return byte_rev_table[byte];
}
unsigned short bitrev16(unsigned short x)
{
return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
}
/**
* bitrev32 - reverse the order of bits in a unsigned int value
* @x: value to be bit-reversed
*/
unsigned int bitrev32(unsigned int x)
{
return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
}

11.1.8

1.8

: 100 200 double.


/++:
#define M
#define N

100
200

void s(double *a, double *b, double *c)


{
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
*(c+i*M+j)=*(a+i*M+j) + *(b+i*M+j);
};

11.1.9

1.9

: 100*200 100*300 double, :


100*300.
/++:
#define M
#define N
#define P

100
200
300

void m(double *a, double *b, double *c)


{
for(int i=0;i<M;i++)
for(int j=0;j<P;j++)
{
*(c+i*M+j)=0;
for (int k=0;k<N;k++) *(c+i*M+j)+=*(a+i*M+j) * *(b+i*M+j);
}
};

11.1.10

1.11

: Task Manager / - NtQuerySystemInformati


..., ..., ...), .
, Task Manager
/.

323

11.2.

11.2

11.2.1

2.1

11.

#1: ,
glibc..
: callback- (1.18),
. quicksort().
.

11.2.2

2.2

: .
.

11.2.3

2.3

11.2.4

2.4

, .

11.2.5

2.5

: , .
0x7F .
.

11.2.6

2.6

.
, .

324

11.3

, : <dennis@yurichev.com>
, ( ), .

325

11.4

, CPU.
, , .

11.5

x86

11.5.1

16-bit (8086/80286), 32-bit (80386, etc), 64-bit.


byte 8-bit. DB.
word 16-bit. DW.
double word (dword) 32-bit. DD.
quad word (qword) 64-bit. DQ.
tbyte (10 ) 80-bit 10 ( IEEE 754 FPU).
Windows API.

11.5.2

R- x86-64, E- 80386. , R 64-, E- 32-.


x86-64 8 : R8-R15.
N.B.: Intel, L: R8L, IDA B: R8B.
RAX/EAX/AX/AL
7 ( )

5 4 3
RAXx64

EAX
AX
AH AL
AKA . - .

326

11.5. X86
RBX/EBX/BX/BL

7 ( )

5 4 3
RBXx64

EBX
BX
BH BL
RCX/ECX/CX/CL
7 ( )

5 4 3
RCXx64

ECX
CX
CH CL

AKA : REP (SHL/SHR/RxL/RxR).


RDX/EDX/DX/DL
7 ( )

5 4 3
RDXx64

EDX
DX
DH DL
RSI/ESI/SI/SIL
7 ( )

5 4 3
RSIx64

ESI
SI
SILx64
AKA source. REP MOVSx, REP CMPSx.
RDI/EDI/DI/DIL
7 ( )

5 4 3
RDIx64

EDI
DI
DILx64
AKA destination. REP MOVSx, REP STOSx.
R8/R8D/R8W/R8L
7 ( )

5 4
R8

1
R8D
R8W
R8L

327

11.5. X86
R9/R9D/R9W/R9L

7 ( )

5 4
R9

R9D
R9W
R9L
R10/R10D/R10W/R10L
7 ( )

5 4
R10

R10D
R10W
R10L
R11/R11D/R11W/R11L
7 ( )

5 4
R11

R11D
R11W
R11L
R12/R12D/R12W/R12L
7 ( )

5 4
R12

R12D
R12W
R12L
R13/R13D/R13W/R13L
7 ( )

5 4
R13

R13D
R13W
R13L
R14/R14D/R14W/R14L
7 ( )

5 4
R14

R14D
R14W
R14L
R15/R15D/R15W/R15L
7 ( )

5 4
R15

1
R15D
R15W
R15L

328

11.5. X86
RSP/ESP/SP/SPL

7 ( )

5 4 3
RSPx64

ESP
SP
SPLx64
AKA . , , .
RBP/EBP/BP/BPL
7 ( )

5 4 3
RBPx64

EBP
BP
BPLx64
AKA frame pointer. - ,
: (1.4.2).
RIP/EIP/IP
7 ( )

5 4
RIPx64

EIP
IP
AKA instruction pointer 3 . . , ( ):
mov eax...
jmp eax

CS/DS/ES/SS/FS/GS
16- (CS), (DS), (SS).
FS win32 TLS, Linux GS.
TLS TIB.
(7.1.3).

AKA EFLAGS.
3

program counter

329

11.5. X86

()
0 (1)

()
CF (Carry)

.
CLC/STC/CMC
//
(1.13.3).

2 (4)
4 (0x10)
6 (0x40)

PF (Parity)
AF (Adjust)
ZF (Zero)

7 (0x80)
8 (0x100)

SF (Sign)
TF (Trap)

9 (0x200)

IF (Interrupt enable)

10 (0x400)

DF (Direction)

11 (0x800)
12, 13 (0x3000)
14 (0x4000)
16 (0x10000)

OF (Overflow)
IOPL (I/O privilege level)80286
NT (Nested task)80286
RF (Resume)80386

17 (0x20000)
18 (0x40000)
19 (0x80000)
20 (0x100000)
21 (0x200000)

VM (Virtual 8086 mode)80386


AC (Alignment check)80486
VIF (Virtual interrupt)Pentium
VIP (Virtual interrupt pending)Pentium
ID (Identification)Pentium

0
0.
.
.
,
.
.
CLI/STI
/

REP MOVSx, REP CMPSx, REP LODSx, REP SCASx.
CLD/STD
/
.

.
,
CPU DRx.

11.5.3

FPU-

8 80- : ST(0)-ST(7). N.B.: IDA ST(0) ST.


IEEE 754.

. 11.1: long double4


FPU.
4

wikipedia

330

11.5. X86

0
1
2
3
4
5
7
8, 9

()
IM (Invalid operation Mask)
DM (Denormalized operand Mask)
ZM (Zero divide Mask)
OM (Overflow Mask)
UM (Underflow Mask)
PM (Precision Mask)
IEM (Interrupt Enable Mask)
PC (Precision Control)

10, 11

RC (Rounding Control)

12

IC (Infinity Control)

, 1 ()

00 24 (REAL4)
10 53 (REAL8)
11 64 (REAL10)

00 ( )
01
10 +
11 0
0 ( ) +
1 +

PM, UM, OM, ZM, DM, IM ,


.

.

15
14
13, 12, 11
10
9
8
7
6
5
4
3
2
1
0

()
B (Busy)
C3
TOP
C2
C1
C0
IR (Interrupt Request)
SF (Stack Fault)
P (Precision)
U (Underflow)
O (Overflow)
Z (Zero)
D (Denormalized)
I (Invalid operation)

FPU (1) (0)


,

SF, P, U, O, Z, D, I .
C3, C2, C1, C0 : (1.13.3).
N.B.: ST(x), FPU TOP 8 .
Tag Word
.

331

11.5. X86

15, 14
13, 12
11, 10
9, 8
7, 6
5, 4
3, 2
1, 0

()
Tag(7)
Tag(6)
Tag(5)
Tag(4)
Tag(3)
Tag(2)
Tag(1)
Tag(0)

:
00
01 0
10 (NAN5 , , )
11

11.5.4

SIMD-

MMX-
8 64- : MM0..MM7.
SSE AVX-
SSE: 8 128- : XMM0..XMM7. x86-64 8 : XMM8..XMM15.
AVX 256 .

11.5.5

.. hardware breakpoints.
DR0 #1
DR1 #2
DR2 #3
DR3 #4
DR6
DR7
DR6
()
0 (1)
1 (2)
2 (4)
3 (8)
13 (0x2000)
14 (0x4000)
15 (0x8000)
5

B0 #1
B1 #2
B2 #3
B3 #4
BD DRx.
GD .
BS single step ( TF EFLAGS).
. .
BT (task switch flag)

Not a Number

332

11.5. X86

N.B. single step .


TF EFLAGS (11.5.2).
DR7
.
()
0 (1)
1 (2)
2 (4)
3 (8)
4 (0x10)
5 (0x20)
6 (0x40)
7 (0x80)
8 (0x100)
9 (0x200)
13 (0x2000)
16,17 (0x30000)
18,19 (0xC0000)
20,21 (0x300000)
22,23 (0xC00000)
24,25 (0x3000000)
26,27 (0xC000000)
28,29 (0x30000000)
30,31 (0xC0000000)

L0 #1
G0 #1
L1 #2
G1 #2
L2 #3
G2 #3
L3 #4
G3 #4
LE P6
GE P6
GD - MOV
DRx-
#1: R/W
#1: LEN
#2: R/W
#2: LEN
#3: R/W
#3: LEN
#4: R/W
#4: LEN

(R/W):
00
01
10 I/O- ( user-mode)
11 ( )
N.B.: .
(LEN):
00 1
01 2
10 32- , 8 64-
11 4

11.5.6

(M) : , ,
, .. compiler intrinsic (8.1).
. [11] [1]
.
333

11.5. X86

LOCK .
, , , . , ,
. ADD, AND, BTR, BTS, CMPXCHG, OR, XADD, XOR.
(5.3).
REP MOVSx STOSx instructions: , CX/ECX/RCX. , MOVSx (11.5.6) STOSx (11.5.6).
REP DF, .
REPE/REPNE (AKA REPZ/REPNZ) CMPSx SCASx instructions:
, CX/ECX/RCX.
ZF 0 (REPE) ZF 1 (REPNE).
, CMPSx (11.5.6) SCASx (11.5.6).
REPE/REPNE DF, .

.
ADC (add with carry) , CF.
, , 64- 32- ADD ADC, :
; 64- : val1 val2.
; .lo 32 , .hi -
ADD val1.lo, val2.lo
ADC val1.hi, val2.hi ; CF

ADD
AND
CALL -: PUSH address_after_CALL_instruction; JMP label
CMP , SUB,
DEC . CF .
IMUL
INC . CF .
JCXZ, JECXZ, JRCXZ (M) CX/ECX/RCX=0
JMP
Jcc ( cc condition code)
( AKA), .
.
JAE AKA JNC: (): CF=0
JA AKA JNBE: (): CF=0 ZF=0
JBE (): CF=1 ZF=1
JB AKA JC: (): CF=1
334

11.5. X86
JC AKA JB: CF=1

JE AKA JZ: : ZF=1


JGE (): SF=OF
JG (): ZF=0 SF=OF
JLE (): ZF=1 SF=OF
JL (): SF=OF
JNBE (): CF=0 ZF=0
JNB AKA JNC: (): CF=0
JNC AKA JAE: CF=0, JNB.
JNE AKA JNZ: : ZF=0
JNGE (): SF=OF
JNG (): ZF=1 SF=OF
JNLE (): ZF=0 SF=OF
JNL (): SF=OF
JNO : OF=0
JNS SF
JNZ AKA JNE: : ZF=0
JO : OF=1
JPO PF
JP AKA JPE: PF
JS SF
JZ AKA JE: : ZF=1
JNAE AKA JC: () CF=1
JNA () CF=1 ZF=1
LAHF AH
LEA (Load Effective Address)
, 6 .
, .
LEA , CPU.
int f(int a, int b)
{
return a*8+b;
};

Listing 11.1: MSVC 2010 /Ox


_a$ = 8
_b$ = 12
_f
PROC
mov
mov
lea
ret
_f
ENDP

; size = 4
; size = 4
eax, DWORD PTR _b$[esp-4]
ecx, DWORD PTR _a$[esp-4]
eax, DWORD PTR [eax+ecx*8]
0

Intel C++ LEA :


6

. : http://en.wikipedia.org/wiki/Addressing_mode

335

11.5. X86

int f1(int a)
{
return a*13;
};

Listing 11.2: Intel C++ 2011


_f1

PROC NEAR
mov
ecx, DWORD PTR [4+esp]
lea
edx, DWORD PTR [ecx+ecx*8]
lea
eax, DWORD PTR [edx+ecx*4]
ret

; ecx = a
; edx = a*9
; eax = a*9 + a*4 = a*13

IMUL .
MOVSB/MOVSW/MOVSD/MOVSQ / 16- / 32- / 64-
SI/ESI/RSI DI/EDI/RDI.
REP, ,
CX/ECX/RCX: memcpy() .
, memcpy() REP MOVSx,
.
memcpy(EDI, ESI, 15):
;
CLD
;
MOV ECX, 3
REP MOVSD
;
MOVSW
;
MOVSB
;

15 ESI EDI
""
12
2

(, 15 REP MOVSB).
MOVSX .: (1.11.1)
MOVZX .: (1.11.1)
MOV . ( ),
: LOAD -
.
: 32- MOV 16- ,
16 . 64- 32-
, 32 .
, x86-64.
MUL
NEG : =
NOP NOP. 0x90, XCHG EAX,EAX.
x86 ( RISC) NOP-. : (3.2)
NOT op1: 1 = 1.
OR
POP : value=SS:[ESP]; ESP=ESP+4 (or 8)
PUSH : ESP=ESP-4 (or 8); SS:[ESP]=value
RET : : POP tmp; JMP tmp. , RET ,
Windows *NIX RETN (return near) , MS-DOS, (7.1.3), RETF (return far).
336

11.5. X86
SAHF AH , .: 1.13.3

SBB (subtraction with borrow) , CF . , , 64-


32- SUB SBB, :
; 64- : val2 val1
; .lo 32 , .hi -
SUB val1.lo, val2.lo
SBB val1.hi, val2.hi ; CF

SCASB/SCASW/SCASD/SCASQ (M) / 16- / 32- / 64- AX/EAX/RAX , DI/EDI/RDI.


CMP.
REPNE: ,
AX/EAX/RAX. NE REPNE: .
- strlen(), ASCIIZ-:
:
lea
edi,
mov
ecx,
xor
eax,
repne scasb
add
edi,

string
0FFFFFFFFh ; 2^32-1 , .., ""
eax
; 0
0FFFFFFFFh ;

; EDI ASCIIZ-.
;
; ECX = -1-strlen
not
dec

ecx
ecx

; ECX

AX/EAX/RAX, - -
memchr(), .., .
SHL

CF

SHR :

CF

STOSB/STOSW/STOSD/STOSQ / 16- / 32- / 64- AX/EAX/RAX


, DI/EDI/RDI.
REP, ,
CX/ECX/RCX: memset() .
337

11.5. X86

, memset() REP STOSx,


.
memset(EDI, 0xAA, 15):
; 15 0xAA EDI
CLD
; ""
MOV EAX, 0AAAAAAAAh
MOV ECX, 3
REP STOSD
; 12
STOSW
; 2
STOSB
;

(, 15 REP STOSB).
SUB . SUB reg,reg
reg.
TEST AND, , .: 1.15
XCHG
XOR op1, op2: XOR . 1 = 1 2. XOR reg,reg
reg.

BSF bit scan forward, .: 1.19.2
BSR bit scan reverse
BTC bit test and complement
BTR bit test and reset
BTS bit test and set
BT bit test
CBW, CWDE, CDQ : ; ;

CLD DF.
CLI (M) IF
CMC (M) CF
CMOVcc MOV:
Jcc (11.5.6).
CMPSB/CMPSW/CMPSD/CMPSQ (M) / 16- / 32- / 64-
SI/ESI/RSI , DI/EDI/RDI.
CMP.
REPE, ,
CX/ECX/RCX, ZF=0 (..,
, E REPE).
memcmp() .
Windows NT (Windows Research Kernel v1.2):

338

11.5. X86

Listing 11.3: base\ntos\rtl\i386\movemem.asm

; ULONG
; RtlCompareMemory (
;
IN PVOID Source1,
;
IN PVOID Source2,
;
IN ULONG Length
;
)
;
; Routine Description:
;
;
This function compares two blocks of memory and returns the number
;
of bytes that compared equal.
;
; Arguments:
;
;
Source1 (esp+4) - Supplies a pointer to the first block of memory to
;
compare.
;
;
Source2 (esp+8) - Supplies a pointer to the second block of memory to
;
compare.
;
;
Length (esp+12) - Supplies the Length, in bytes, of the memory to be
;
compared.
;
; Return Value:
;
;
The number of bytes that compared equal is returned as the function
;
value. If all bytes compared equal, then the length of the original
;
block of memory is returned.
;
;-RcmSource1
RcmSource2
RcmLength

equ
equ
equ

[esp+12]
[esp+16]
[esp+20]

CODE_ALIGNMENT
cPublicProc _RtlCompareMemory,3
cPublicFpo 3,0
push
push
cld
mov
mov
;
;
;

save registers

;
;
;
;
;

(ecx) = length in bytes


(ecx) = length in dwords
no dwords, try bytes
compare dwords
mismatch, go find byte

;
;
;
;
;

(ecx) = length in bytes


(ecx) = length mod 4
0 odd bytes, go do dwords
compare odd bytes
mismatch, go report how far we got

clear direction
(esi) -> first block to compare
(edi) -> second block to compare

mov
shr
jz
repe
jnz

ecx,RcmLength
ecx,2
rcm20
cmpsd
rcm40

Compare residual bytes, if any.

rcm20:

;
;
;

esi,RcmSource1
edi,RcmSource2

;
;
;
;
;

Compare dwords, if any.

rcm10:

;
;
;

esi
edi

mov
and
jz
repe
jnz

ecx,RcmLength
ecx,3
rcm30
cmpsb
rcm50

All bytes in the block match.

rcm30:

mov
pop
pop
stdRET

eax,RcmLength
edi
esi
_RtlCompareMemory

; set number of matching bytes


; restore registers
;

339

11.5. X86
;
;
;
;

When we come to rcm40, esi (and edi) points to the dword after the
one which caused the mismatch. Back up 1 dword and find the byte.
Since we know the dword didnt match, we can assume one byte wont.

rcm40:

;
;
;
;

sub
sub
mov
repe

esi,4
edi,4
ecx,5
cmpsb

;
;
;
;

back up
back up
ensure that ecx doesnt count out
find mismatch byte

When we come to rcm50, esi points to the byte after the one that
did not match, which is TWO after the last byte that did match.

rcm50:

dec
sub
mov
pop
pop
stdRET

esi
esi,RcmSource1
eax,esi
edi
esi
_RtlCompareMemory

; back up
; compute bytes that matched
;
; restore registers
;

stdENDP _RtlCompareMemory

N.B.: - 32- (CMPSD) 4- ,


(CMPSB) .
CPUID CPU. .: (1.16.6).
DIV
IDIV
INT (M): INT x PUSHF; CALL dword ptr [x*4] 16- . MS-DOS, . AX/BX/CX/DX/SI/DI
( ). (2 ) MS-DOS -
. IRET.
MS-DOS 0x21, API7 . . [4]
MS-DOS.
MS-DOS, , Linux Windows
(5.2), SYSENTER SYSCALL.
INT 3 (M): INT, 1- (0xCC),
. , 0xCC , , . Windows NT, EXCEPTION_BREAKPOINT , CPU .
, . , Windows . MSVS8
, . reverse
engineering, - .
MSVC compiler intrinsic : __debugbreak()9 .
win32 - kernel32.dll DebugBreak()10 ,
INT 3.
7

Application programming interface


Microsoft Visual Studio
9
http://msdn.microsoft.com/en-us/library/f408b4et.aspx
10
http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297(v=vs.85).aspx
8

340

11.5. X86

IN (M) . OS
MS-DOS, (7.1.3).
IRET : MS-DOS ,
INT. POP tmp; POPF; JMP tmp.
LOOP (M) CX/ECX/RCX, .
OUT (M) . OS
MS-DOS, (7.1.3).
POPA (M) (R|E)DI, (R|E)SI, (R|E)BP, (R|E)BX, (R|E)DX, (R|E)CX, (R|E)AX
.
POPCNT population count. 1 . AKA hamming weight.
AKA NSA instruction - :
This branch of cryptography is fast-paced and very politically charged. Most designs
are secret; a majority of military encryptions systems in use today are based on LFSRs. In
fact, most Cray computers (Cray 1, Cray X-MP, Cray Y-MP) have a rather curious instruction
generally known as population count. It counts the 1 bits in a register and can be
used both to efficiently calculate the Hamming distance between two binary words and
to implement a vectorized version of a LFSR. Ive heard this called the canonical NSA
instruction, demanded by almost all computer contracts.

[24]
POPF (AKA EFLAGS)
PUSHA (M) (R|E)AX, (R|E)CX, (R|E)DX, (R|E)BX, (R|E)BP, (R|E)SI, (R|E)DI .
PUSHF (AKA EFLAGS)
RCL (M) CF:
7

CF

CF

RCR (M) CF:


CF

CF

ROL/ROR (M)
ROL: :

CF

341

11.5. X86
ROR: :

CF

CPU , /++ ,
11 .
, MSVC (compiler intrinsics)
_rotl() _rotr()12 , .
SAL , SHL
SAR
7

CF

, MSB13 .
SETcc op: 1 op ( ) 0 .
Jcc (11.5.6).
STC (M) CF
STD (M) DF
STI (M) IF
SYSCALL (AMD) (5.2)
SYSENTER (Intel) (5.2)
UD2 (M) , . .
FPU
-R , -P
, -PP .
-P , FPU-.
FABS ST(0) ST(0)
FADD op: ST(0)=op+ST(0)
FADD ST(0), ST(i): ST(0)=ST(0)+ST(i)
FADDP ST(1)=ST(0)+ST(1); , ,

11


http://msdn.microsoft.com/en-us/library/5cc576c4.aspx
13
Most significant bit/byte ( /)
12

342

11.5. X86
FCHS : ST(0)=-ST(0)

FCOM ST(0) ST(1)


FCOM op: ST(0) op
FCOMP ST(0) ST(1);
FCOMPP ST(0) ST(1);
FDIVR op: ST(0)=op/ST(0)
FDIVR ST(i), ST(j): ST(i)=ST(j)/ST(i)
FDIVRP op: ST(0)=op/ST(0);
FDIVRP ST(i), ST(j): ST(i)=ST(j)/ST(i);
FDIV op: ST(0)=ST(0)/op
FDIV ST(i), ST(j): ST(i)=ST(i)/ST(j)
FDIVP ST(1)=ST(0)/ST(1); , ,

FILD op: op .
FIST op: ST(0) op
FISTP op: ST(0) op;
FLD1 1
FLDCW op: FPU control word (11.5.3) 16-bit op.
FLDZ
FLD op: op .
FMUL op: ST(0)=ST(0)*op
FMUL ST(i), ST(j): ST(i)=ST(i)*ST(j)
FMULP op: ST(0)=ST(0)*op;
FMULP ST(i), ST(j): ST(i)=ST(i)*ST(j);
FSINCOS : tmp=ST(0); ST(1)=sin(tmp); ST(0)=cos(tmp)

FSQRT : (0) = (0)


FSTCW op: FPU control word (11.5.3) 16-bit op .
FNSTCW op: FPU control word (11.5.3) 16-bit op.
FSTSW op: FPU status word (11.5.3) 16-bit op .
FNSTSW op: FPU status word (11.5.3) 16-bit op.
FST op: ST(0) op
FSTP op: ST(0) op;
FSUBR op: ST(0)=op-ST(0)
343

11.6. ARM
FSUBR ST(0), ST(i): ST(0)=ST(i)-ST(0)

FSUBRP ST(1)=ST(0)-ST(1); , ,

FSUB op: ST(0)=ST(0)-op
FSUB ST(0), ST(i): ST(0)=ST(0)-ST(i)
FSUBP ST(1)=ST(1)-ST(0); , ,
FUCOM ST(i): ST(0) ST(i)
FUCOM : ST(0) ST(1)
FUCOMP : ST(0) ST(1); .
FUCOMPP : ST(0) ST(1); .
FCOM,
SNaN, QNaN .
FXCH ST(i) ST(0) ST(i)
FXCH ST(0) ST(1)
SIMD-

11.6

ARM

11.6.1

R0 - R0
R1
R2
R3
R4
R5
R6
R7
R8
R9
R10
R11
R12
R13 AKA SP ( )
R14 AKA LR (link register)
R15 AKA PC (program counter)
R0-R3 scratch registers: - , -.
344

11.6. ARM

11.6.2

Current Program Status Register (CPSR)

0..4
5
6
7
8
9
10..15, 25, 26
16..19
20..23
24
27
28
29
30
31

11.6.3

M processor mode
T Thumb state
F FIQ disable
I IRQ disable
A imprecise data abort disable
E data endianness
IT if-then state
GE greater-than-or-equal-to
DNM do not modify
J Java state
Q sticky overflow
V overflow
C carry/borrow/extend
Z zero bit
N negative/less than

VPF ( ) NEON
0..31bits

32..64 65..96
Q0128 bits

D064 bits
S032 bits S1

S2

97..127
D1
S3

S- 32-, .
D- 64-, .
D- S- CPU D-
S- ( ).
, NEON Q- 128
CPU .
VFP 32 S-: S0..S31.
VPFv2 16 D-, S0..S31.
VFPv3 (NEON Advanced SIMD) 16 D-, D0..D31,
D16..D31 S-.
NEON Advanced SIMD 16 128- Q-, D0..D31.

345


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
RA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
PE Portable Executable
SP Stack Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
DLL Dynamic-link library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
PC Program Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
LR Link Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
IDA Interactive Disassembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
IAT Import Address Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
RVA Relative Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
VA Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
OEP Original Entry Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
MSVC Microsoft Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

346


MSVS Microsoft Visual Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
ASLR Address Space Layout Randomization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
MFC Microsoft Foundation Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
TLS Thread Local Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
AKA Also Known As ( )
CRT C runtime library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
CPU Central processing unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
FPU Floating-point unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
CISC Complex instruction set computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
RISC Reduced instruction set computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
GUI Graphical user interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
RTTI Run-time type information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
SIMD Single instruction, multiple data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
BSOD Black Screen of Death . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
ISA Instruction Set Architecture ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
CGI Common Gateway Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
HPC High-Performace Computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
SOC System on Chip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
SEH Structured Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
ELF , Linux *NIX . . . . . . . . . . . . . . . . . . vii

347


TIB Thread Information Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
TEA Tiny Encryption Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
PIC Position Independent Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
NAN Not a Number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
NOP No OPeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
BEQ (PowerPC, ARM) Branch if Equal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
BNE (PowerPC, ARM) Branch if Not Equal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
BLR (PowerPC) Branch to Link Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
XOR eXclusive OR ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
MCU Microcontroller unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
RAM Random-access memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
ROM Read-only memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
EGA Enhanced Graphics Adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
VGA Video Graphics Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
API Application programming interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
ASCIIZ ASCII Zero (ASCII- ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
IA64 Intel Architecture 64 (Itanium) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
EPIC Explicitly parallel instruction computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
OOE Out-of-order execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
MSDN Microsoft Developer Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii

348


MSB Most significant bit/byte ( /) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
STL (C++) Standard Template Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
PODT (C++) Plain Old Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
HDD Hard disk drive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

349

[1] AMD. AMD64 Architecture Programmers Manual. 2013. Also available as http://developer.amd.
com/resources/documentation-articles/developer-guides-manuals/.
[2] Apple. iOS ABI Function Call Guide. 2010. Also available as http://developer.apple.
com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/
iPhoneOSABIReference.pdf.
[3] blexim. Basic integer overflows. Phrack, 2002. Also available as http://yurichev.com/mirrors/
phrack/p60-0x0a.txt.
[4] Ralf Brown. The x86 interrupt list. Also available as http://www.cs.cmu.edu/~ralf/files.html.
[5] Mike Burrell. Writing effcient itanium 2 assembly code. Also available as http://yurichev.com/
mirrors/RE/itanium.pdf.
[6] Marshall Cline. C++ faq. Also available as http://www.parashift.com/c++-faq-lite/index.
html.
[7] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms,
Third Edition. The MIT Press, 3rd edition, 2009.
[8] Agner Fog. The microarchitecture of Intel, AMD and VIA CPUs / An optimization guide for assembly
programmers and compiler makers. 2013. http://agner.org/optimize/microarchitecture.
pdf.
[9] Agner Fog. Optimizing software in C++: An optimization guide for Windows, Linux and Mac platforms.
2013. http://agner.org/optimize/optimizing_cpp.pdf.
[10] IBM. PowerPC(tm) Microprocessor Family: The Programming Environments for 32-Bit Microprocessors.
2000. Also available as http://yurichev.com/mirrors/PowerPC/6xx_pem.pdf.
R
[11] Intel.
Intel
64 and IA-32 Architectures Software Developers Manual Combined
Volumes:1, 2A, 2B, 2C, 3A, 3B, and 3C.
2013.
Also available as http:
//www.intel.com/content/dam/www/public/us/en/documents/manuals/
64-ia-32-architectures-software-developer-manual-325462.pdf.

[12] ISO. ISO/IEC 9899:TC3 (C C99 standard). 2007. Also available as http://www.open-std.org/jtc1/
sc22/WG14/www/docs/n1256.pdf.
[13] ISO. ISO/IEC 14882:2011 (C++ 11 standard). 2013. Also available as http://www.open-std.org/
jtc1/sc22/wg21/docs/papers/2013/n3690.pdf.
[14] Brian W. Kernighan. The C Programming Language. Prentice Hall Professional Technical Reference, 2nd
edition, 1988.
[15] Donald E. Knuth. The Art of Computer Programming Volumes 1-3 Boxed Set. Addison-Wesley Longman
Publishing Co., Inc., Boston, MA, USA, 2nd edition, 1998.
[16] Eugene Loh. The ideal hpc programming language. Queue, 8(6):30:3030:38, June 2010.
350

[17] Advanced RISC Machines Ltd. The ARM Cookbook. 1994. Also available as http://yurichev.com/
ref/ARM%20Cookbook%20(1994).
[18] Aleph One. Smashing the stack for fun and profit. Phrack, 1996. Also available as http://yurichev.
com/mirrors/phrack/p49-0x0e.txt.
[19] Matt Pietrek. An in-depth look into the win32 portable executable file format. MSDN magazine, 2002.
[20] Eric S. Raymond. The Art of UNIX Programming. Pearson Education, 2003. Also available as http:
//catb.org/esr/writings/taoup/html/.
[21] Dennis M. Ritchie. Where did ++ come from? (net.lang.c). http://yurichev.com/mirrors/C/c_
dmr_postincrement.txt, 1986. [Online; accessed 2013].
[22] Dennis M. Ritchie. The development of the c language. SIGPLAN Not., 28(3):201208, March
1993. Also available as http://yurichev.com/mirrors/C/dmr-The%20Development%20of%
20the%20C%20Language-1993.pdf.
R Internals: Including Windows
[23] Mark E. Russinovich and David A. Solomon with Alex Ionescu. Windows
Server 2008 and Windows Vista, Fifth Edition. 2009.

[24] Bruce Schneier. Applied Cryptography: Protocols, Algorithms, and Source Code in C. 1994.
[25] SunSoft Steve Zucker and IBM Kari Karhi. SYSTEM V APPLICATION BINARY INTERFACE: PowerPC Processor
Supplement. 1995. Also available as http://yurichev.com/mirrors/PowerPC/elfspec_ppc.
pdf.
[26] trew. Introduction to reverse engineering win32 applications. uninformed. Also available as http:
//yurichev.com/mirrors/RE/uninformed_v1a7.pdf.
[27] Henry S. Warren. Hackers Delight. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 2002.
[28] Dennis Yurichev. Finding unknown algorithm using only input/output pairs and z3 smt solver. 2012. Also
available as http://yurichev.com/writings/z3_rockey.pdf.
[29] Dennis Yurichev. /++. 2013. Also available as http://
yurichev.com/writings/C-notes-ru.pdf.

351

Glossary


1. 42, 48, 51, 334, 337, 341
1. 42, 48, 233, 250, 334
. 114
. SP/ESP/RSP x86. 2, 3, 6, 9, 11, 1416, 21, 181
183, 329, 344
( , .., ) : http://en.wikipedia.org/
wiki/Tail_call. 179
. 88
anti-pattern . 10
atomic operation , . 211, 289
basic block , . IDA - . 192, 194
callee -. 184
compiler intrinsic - -.
. ,
CPU. : (8.1). 340
dongle LPT- ( ) USB.
security token-, , , (-) .. 214
endianness : https://en.wikipedia.org/wiki/Endianness. 8
heap () , ,
. malloc()/free() .. 11, 93, 149, 152, 164, 165, 203
kernel mode CPU OS .
. user mode.. 353
keygenme , /. 319
leaf function - -. 10
link register (RISC) . leaf-
, .., .. 10, 215, 344
352

Glossary
Glossary
loop unwinding ,
, . 44
NaN : , .
63, 192
NEON AKA Advanced SIMD SIMD14 ARM. 345
NOP no operation, . 202
POKE BASIC . 202
register allocator - .
47, 81, 123
reverse engineering , , . vii,
viii, 340
thunk function : .. 8, 215, 223
user mode CPU . . kernel
mode.. 228, 352
Windows NT Windows NT, 2000, XP, Vista, 7, 8. 120, 204, 210, 340

14

Single instruction, multiple data

353


.NET, 209
AT&T, 4, 13

, 19, 21, 29, 110, 122
-, 50
-, 50
-, 50
-, 50
C99
bool, 79
restrict, 128
variable length arrays, 77
const, 2, 23
for, 42, 90
if, 30, 35
restrict, 128
return, 2, 24, 28
switch, 3436
while, 46

alloca(), 11, 77
assert(), 197
atexit(), 154
atoi(), 320
calloc(), 244
close(), 188
longjmp(), 36
malloc(), 94
memchr(), 337
memcmp(), 199, 338
memcpy(), 4, 19, 336
memset(), 281, 337
open(), 188
qsort(), 110, 324
rand(), 195, 232, 320
read(), 188
scanf(), 18
srand(), 320
strcmp(), 189
strcpy(), 4, 233
strlen(), 46, 119, 337
strstr(), 321
tolower(), 249
toupper(), 320

, 85, 285
++, 272
C++11, 164, 188
ostream, 147
References, 148
STL
std::forward_list, 163
std::list, 155
std::map, 170
std::set, 170
std::string, 149
std::vector, 163
grep, 65, 195, 199, 202, 270
, 203
, 8
, 170
, 21
-, 225
, 23, 134
RISC, 33
- (NaNs), 63
, 72
Intel, 4, 5
- , 5, 185
, 23
, 23
, 9, 179
Tail recursion, 179
, 9, 25, 35
, 9
, 20
, 35, 98
iPod/iPhone/iPad, 4
8080, 50
8086, 228
80286, 228, 233
80386, 233
Angry Birds, 65
ARM, 50, 214
ARM, 5
, 40
, 27, 41
354


, 50
, 8

ADD, 7, 32, 36, 45, 53, 88


ADDAL, 32
ADDCC, 40
ADDS, 28, 36
ADR, 5, 32
ADREQ, 32, 36
ADRGT, 32
ADRHI, 33
ADRNE, 36
ASRS, 53, 85
B, 15, 32, 33
BCS, 33, 66
BEQ, 25, 36
BGE, 33
BIC, 85
BL, 68, 32
BLE, 33
BLEQ, 32
BLGT, 32
BLHI, 33
BLS, 33
BLT, 45
BLX, 8
BNE, 33
BX, 27, 41
CMP, 25, 32, 36, 40, 45, 88
IDIV, 52
IT, 65, 76
LDMCSFD, 33
LDMEA, 9
LDMED, 9
LDMFA, 9
LDMFD, 6, 9, 32
LDMGEFD, 32
LDR, 16, 21, 69
LDR.W, 79
LDRB, 101
LDRB.W, 50
LDRSB, 50
LSL, 88
LSL.W, 88
LSLS, 70
MLA, 27
MOV, 6, 53, 88
MOVT, 7, 53
MOVT.W, 8
MOVW, 8
MULS, 28
MVNS, 51
ORR, 85
POP, 5, 6, 9, 10


PUSH, 9, 10
RSB, 79, 88
SMMUL, 53
STMEA, 9
STMED, 9
STMFA, 9, 17
STMFD, 5, 9
STMIA, 16
STMIB, 17
STR, 16, 69
SUB, 16, 79, 88
SUBEQ, 51
SXTB, 102
TEST, 47
TST, 83, 88
VADD, 57
VDIV, 57
VLDR, 57
VMOV, 57, 64
VMOVGT, 64
VMRS, 64
VMUL, 57

APSR, 64
FPSCR, 64
Link Register, 6, 10, 15, 42, 344
R0, 28, 344
scratch registers, 50, 344
Z, 25, 345
thumb, 5, 33, 41
thumb-2, 5, 41, 65, 66
armel, 58
armhf, 58
Condition codes, 32
D-, 57, 345
Data processing instructions, 53
DCB, 6
hard float, 58
if-then block, 65
Leaf function, 10
Optional operators
ASR, 53, 88
LSL, 69, 79, 88
LSR, 53, 88
ROR, 88
RRX, 88
S-, 57, 345
soft float, 58
ASLR, 204
BASIC
POKE, 202
binary grep, 199, 213
BIND.EXE, 208
355


Bitcoin, 286
BSoD, 209
BSS, 205
C11, 188
Callbacks, 110
Canary, 73
cdecl, 14, 181
COFF, 221
column-major order, 77
Compiler intrinsic, 12, 285
CRC32, 88, 225
cygwin, 197, 209, 213
DES, 113, 123
dlopen(), 189
dlsym(), 189
DosBox, 202
double, 54, 185
dtruss, 213
ELF, 22
Error messages, 197
fastcall, 81, 182
float, 54, 106, 185, 330
FORTRAN, 77, 128
Function epilogue, 15, 16, 32, 101, 179, 201
Function prologue, 3, 10, 16, 73, 179, 201
Fused multiplyadd, 27
GDB, 73
Hiew, 209
IAT, 203
IDA
var_?, 16, 21
IEEE 754, 54, 106, 108, 326, 330
Inline code, 46, 85, 131, 138
int 0x2e, 210
int 0x80, 210
Intel C++, 2, 114, 192, 285, 335
Itanium, 190
jumptable, 38, 41
Keil, 4
kernel panic, 209
kernel space, 209
LD_PRELOAD, 188
Linux, 272
libc.so.6, 81, 113
LLVM, 4
long double, 54
Loop unwinding, 44


Mac OS Classic, 214
MacOSX, 213
MD5, 198, 225
MFC, 206
MIDI, 198
MIPS, 214
MS-DOS, 75, 198, 202, 203, 228, 340
DOS extenders, 234
MS-DOS , 233
Name mangling, 134
objdump, 187, 209
OEP, 203, 209
OpenMP, 286
OpenWatcom, 293, 294, 302
Oracle RDBMS, 2, 113, 192, 197, 272, 279, 281, 285
Ordinal, 206
Page (memory), 120
PDB, 195, 205, 269
PDP-11, 50
PowerPC, 214
puts() printf(), 7, 20, 31
Raspberry Pi, 4, 58
Register allocation, 123
Relocation, 8
row-major order, 77
RTTI, 147
RVA, 203
SAP, 195, 269
SCO OpenServer, 221
Scratch space, 184
SHA1, 225
SHA512, 286
shellcode, 204, 209
Signed numbers, 31, 181
stdcall, 181
strace, 188, 213
syscall, 209
syscalls, 81, 213
thiscall, 134, 135, 182
ThumbTwoMode, 8
thunk-, 8, 208, 215, 223
TLS, 75, 188, 205, 209, 329
Callbacks, 209
Unrolled loop, 46, 76
uptime, 188
user space, 209
VA, 203

356


Win32, 234
Windows
GetProcAddress, 208
KERNEL32.DLL, 80
LoadLibrary, 208
MSVCR80.DLL, 111
ntoskrnl.exe, 272
Structured Exception Handling, 13
TIB, 75, 329
Windows 2000, 204
Windows NT4, 204
Windows Vista, 203
Windows XP, 204, 209
Windows 3.x, 234
Windows API, 326
Wolfram Mathematica, 54


FDIVR, 56, 343
FDIVRP, 343
FILD, 343
FIST, 343
FISTP, 343
FLD, 59, 60, 343
FLD1, 343
FLDCW, 343
FLDZ, 343
FMUL, 56, 343
FMULP, 343
FNSTCW, 343
FNSTSW, 60, 63, 343
FSINCOS, 343
FSQRT, 343
FST, 343
FSTCW, 343
FSTP, 59, 343
FSTSW, 343
FSUB, 344
FSUBP, 344
FSUBR, 343
FSUBRP, 343
FUCOM, 63, 344
FUCOMP, 344
FUCOMPP, 63, 344
FXCH, 344
IDIV, 340
IMUL, 26, 334
IN, 228, 340
INC, 48, 334
INT, 340
IRET, 340, 341
JA, 31, 181, 334
JAE, 31, 334
JB, 31, 181, 334
JBE, 31, 334
JC, 334
JCXZ, 334
JE, 35, 334
JECXZ, 334
JG, 31, 181, 334
JGE, 31, 334
JL, 31, 181, 334
JLE, 31, 334
JMP, 9, 15, 208, 334
JNA, 334
JNAE, 334
JNB, 334
JNBE, 63, 334
JNC, 334
JNE, 24, 31, 334
JNG, 334
JNGE, 334

x86

ADC, 334
ADD, 2, 14, 26, 334
AND, 3, 80, 83, 86, 105, 334
BSF, 122, 338
BSR, 338
BT, 338
BTC, 338
BTR, 211, 338
BTS, 338
CALL, 2, 9, 207, 334
CBW, 338
CDQ, 338
CLD, 338
CLI, 338
CMC, 338
CMOVcc, 33, 338
CMP, 24, 334
CMPSB, 199, 338
CMPSD, 338
CMPSQ, 338
CMPSW, 338
CPUID, 103, 340
CWDE, 338
DEC, 48, 334
DIV, 340
DIVSD, 201
FABS, 342
FADD, 342
FADDP, 56, 342
FCHS, 342
FCOM, 61, 63, 343
FCOMP, 60, 343
FCOMPP, 343
FDIV, 55, 200, 321, 343
FDIVP, 55, 343
357


JNL, 334
JNLE, 334
JNO, 334
JNS, 334
JNZ, 334
JO, 334
JP, 61, 334
JPO, 334
JRCXZ, 334
JS, 334
JZ, 25, 35, 285, 334
LAHF, 335
LEA, 20, 91, 96, 335
LEAVE, 3
LES, 233
LOCK, 210
LOOP, 42, 201, 341
MOV, 2, 4, 205, 336
MOVDQA, 116
MOVDQU, 116
MOVSB, 336
MOVSD, 248, 336
MOVSQ, 336
MOVSW, 336
MOVSX, 47, 50, 101, 102, 336
MOVZX, 48, 94, 214, 336
MUL, 336
NEG, 336
NOP, 91, 179, 336
NOT, 49, 51, 252, 336
OR, 83, 336
OUT, 228, 341
PADDD, 116
PCMPEQB, 121
PLMULHW, 114
PLMULLD, 114
PMOVMSKB, 121
POP, 2, 9, 336
POPA, 341
POPCNT, 341
POPF, 341
PUSH, 2, 3, 9, 19, 336
PUSHA, 341
PUSHF, 341
PXOR, 121
RCL, 201, 341
RCR, 341
RET, 2, 9, 73, 135, 336
ROL, 285, 341
ROR, 285, 341
SAHF, 63, 336
SAL, 342
SAR, 342
SBB, 337


SCASB, 337
SCASD, 337
SCASQ, 337
SCASW, 337
SETcc, 63, 342
SETNBE, 63
SETNZ, 48
SHL, 68, 86, 337
SHR, 87, 105, 337
STC, 342
STD, 342
STI, 342
STOSB, 337
STOSD, 337
STOSQ, 337
STOSW, 337
SUB, 2, 3, 24, 35, 338
SYSCALL, 340, 342
SYSENTER, 210, 340, 342
TEST, 47, 80, 83, 338
UD2, 342
XADD, 212
XCHG, 338
XOR, 2, 24, 49, 226, 338

, 24
, 61
EAX, 24, 28
EBP, 20, 26
ECX, 134
ESP, 14, 20
JMP, 39
RIP, 187
ZF, 24, 80
8086, 50, 84
80386, 84
80486, 54
AVX, 113
FPU, 54, 330
MMX, 113
SSE, 113
SSE2, 113
x86-64, 19, 122, 183, 187, 326, 332
Xcode, 4

358