Академический Документы
Профессиональный Документы
Культура Документы
<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
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
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!
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
proc near
var_10
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
main
1.
[esp+10h+var_10], eax
_printf
eax, 0
:
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.
.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
, , 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.
, Keil:
armcc.exe --arm --c90 -O0 1.c
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}
, 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
( 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}
19
_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}
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.
_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
, : 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);
};
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
...
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]
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()
1.3.1
x86
...
push
push
push
push
call
add
3
2
1
OFFSET $SG3830
_printf
esp, 16
; 00000010H
, , , printf()
: .
44
45
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
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
1.3.2
ARM: 3 printf()
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}
, 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
(-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}
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
loc_3E
B0
BD
, 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}
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
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
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}
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.
:
_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 ?
;
;
;
;
;
;
;
;
;
;
;
_x ?, . ,
.exe , . .exe . . ,
.
Linux . x ,
_bss. ELF :
; Segment type: Uninitialized
; Segment permissions: Read/Write
- , 10,
_data, :
; Segment type: Pure data
; Segment permissions: Read/Write
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}
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
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, 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
loc_1A
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
; size = 4
; size = 4
; size = 4
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.
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
50
ebp
ebp,
eax,
eax,
eax,
ebp
esp
[ebp+arg_0]
[ebp+arg_4]
[ebp+arg_8]
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
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
1.6
x86 53 EAX,
(char), EAX AL. , FPU ST(0) . ARM
R0.
envp
argv
argc
main
eax
exit
.., :
exit(main(argc,argv,envp));
, 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
28
1.7.
1.
return rt;
};
; 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
;
;
;
;
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
...
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
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
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
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
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
loc_8C
locret_96
70 BD
; "a==b\n"
; "a<b\n"
POP
{R4-R6,PC}
; End of function f_signed
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
__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
, 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
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
mov
loc_80483FE:
loc_804840C:
38
1.9. SWITCH()/CASE/DEFAULT
1.
call
jmp
_puts
short locret_8048450
mov
call
jmp
mov
call
jmp
mov
call
jmp
mov
call
loc_804841A:
loc_8048428:
loc_8048436:
loc_8048444:
locret_8048450:
f
off_804855C
dd
dd
dd
dd
dd
offset
offset
offset
offset
offset
loc_80483FE
loc_804840C
loc_804841A
loc_8048428
loc_8048436
, : 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
04 00 00 EA
05 00 00 EA
06 00 00 EA
07 00 00 EA
EC 00 8F E2
06 00 00 EA
ADR
R0, aZero
B
loc_1B8
; ------------------------------------------------------------------------one_case
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
ADR
R0, aTwo
B
loc_1B8
; ------------------------------------------------------------------------three_case
01 0C 8F E2
00 00 00 EA
ADR
R0, aThree
B
loc_1B8
; ------------------------------------------------------------------------four_case
01 0C 8F E2
ADR
R0, aFour
loc_1B8
66 18 00 EA
B
__2printf
; ------------------------------------------------------------------------default_case
D4 00 8F E2
FC FF FF EA
ADR
B
; End of function f2
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
8D A0
06 E0
one_case
8E A0
04 E0
two_case
8F A0
02 E0
three_case
90 A0
00 E0
four_case
91 A0
ADR
R0, aFour
loc_118
06 F0 6A F8
10 BD
BL
__2printf
POP
{R4,PC}
; ------------------------------------------------------------------------default_case
82 A0
FA E7
ADR
B
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
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,
: 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
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
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
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
R0, R4
f
R4, R4, #1
CMP
BLT
MOV
LDMFD
R4, #0xA
loc_35C
R0, #0
SP!, {R4,PC}
loc_368
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
, .
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
;
;
;
;
;
;
eax=eos
eax
eax eos
edx==0?
, edx ,
;
mov
eax,
sub
eax,
sub
eax,
mov
esp,
pop
ebp
ret
0
_strlen_ ENDP
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
. ,
.
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
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
= -8
= -4
SUB
STR
LDR
STR
SP,
R0,
R0,
R0,
loc_2CB8
R0,
R1,
R0,
R0,
SP,
LR
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
loc_2DF6
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
, 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
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
_f
mov
mov
imul
sar
mov
shr
add
ret
ENDP
; size = 4
ecx,
eax,
ecx
edx,
eax,
eax,
eax,
0
; 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
[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
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
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
53
1.13. FPU
1.12.3
1.
, :
mov
imul
sar
mov
shr
add
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
; : ST(0) = _a 3.13
fld
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
[ebp+arg_8]
; : ST(0) = , ST(1) =
pop
faddp
ebp
st(1), st
; : ST(0) =
retn
endp
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
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
58
1.13. FPU
ret
_main
1.
0
ENDP
= -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
, 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
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
;
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
60
1.13. FPU
a=b, : 1, 0, 0.
1.
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) 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(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.
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
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
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
1.13. FPU
1.
, 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
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
CMP
BLT
MOV
ADD
LDMFD
R4, #20
loc_4B0
R0, #0
SP, SP, #0x50
SP!, {R4,PC}
;
;
;
;
; 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
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
;
;
;
;
;
;
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}
; 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
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
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
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
; 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.
[stack]
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
-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]
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
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
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=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
=
=
=
=
-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,
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
;
;
;
R3, [R0,R2,LSL#2] ;
;
LR
, .
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.
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)
test
mov
jz
jmp
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
99
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
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
TST
BNE
LDR
ADD
LDR
MOV
STR
LDRB
MOV
CMP
ORRNE
82
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
1.15.2
:
#define IS_SET(flag, bit)
#define SET_BIT(var, bit)
#define REMOVE_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
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
21 89 03
43
11
43
47
MOVS
ORRS
ASRS
BICS
BX
R1,
R0,
R1,
R0,
LR
0x4000
R1
R1, #5
R1
BIC
ORR
BX
, LLVM, , , :
REMOVE_BIT (rt, 0x4200);
SET_BIT (rt, 0x4000);
. 0x4200? ,
LLVM 103 . , , .
, (8.2).
Thumb, Xcode (LLVM) .
103
85
1.15.
1.15.3
1.
/++ .
, -
:
#define IS_SET(flag, bit)
, 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
; 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.
public f
proc near
rt
i
arg_0
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
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
loc_2E54
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
88
1.15.
1.
unsigned long
unsigned char
ub4;
ub1;
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,
89
1.15.
1.
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, 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 ?
;
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
\
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.
(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
92
1.16.
, :
1.
!
. , ,
, , .
, . . , ,
, , .
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
:
Listing 1.89: MSVC
$SG78594 DB
_main
PROC
push
push
call
add
mov
push
call
movzx
movzx
movzx
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
};
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
};
1.16.
1.
, :
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}
= -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
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
100
1.16.
:
1.
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
=
=
=
=
=
-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}
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);
};
; 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
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;
};
; size = 16
; 00000010H
xor
mov
cpuid
push
lea
mov
mov
mov
mov
ecx, ecx
eax, 1
mov
mov
and
push
push
call
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,
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 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
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
mov
shr
and
add
and
shl
mov
and
eax,
eax,
eax,
eax,
eax,
eax,
ecx,
ecx,
;
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
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;
};
DB
__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
; float
fld
;
fsub
fstp
fld
fstp
push
call
add
dec
jne
pop
xor
pop
mov
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
....
.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
1.19
mov
mov
mov
mov
call
edx, [ebp+arg_10]
[esp+4], esi
[esp], edi
[esp+8], edx
[ebp+arg_C]
SIMD
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
cmp
jbe
mov
sub
neg
cmp
jbe
cmp
jnb
mov
sub
cmp
jb
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
mov
add
mov
inc
cmp
jb
mov
mov
mov
lea
loc_36:
loc_55:
loc_67:
loc_7F:
loc_9A:
loc_C1:
loc_D6:
;
;
;
;
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:
movdqu
paddd
movdqa
add
cmp
jb
loc_111:
loc_127:
ecx, edx
short loc_15B
esi, [esp+10h+ar1]
edi, [esp+10h+ar2]
loc_133:
mov
add
mov
inc
cmp
jb
loc_14D:
loc_15B:
xor
eax, eax
pop
ecx
pop
ebx
pop
esi
pop
edi
retn
; --------------------------------------------------------------------------loc_162:
xor
jmp
?f@@YAHHPAH00@Z endp
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
, ,
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:
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:
add
esp, 0Ch
xor
eax, eax
pop
ebx
pop
esi
pop
edi
pop
ebp
retn
; --------------------------------------------------------------------------align 8
loc_80484E8:
test
jnz
lea
cmp
jbe
lea
cmp
ja
cmp
jbe
loc_80484F8:
loc_8048503:
mov
shr
mov
shl
test
mov
jz
mov
mov
xor
xor
nop
loc_8048520:
movdqu
movdqu
add
paddd
movdqa
add
cmp
jb
mov
mov
cmp
jz
lea
add
add
add
lea
edx,
esi,
edi,
ebx,
esi,
loc_8048547:
loc_8048558:
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_
eax, esi
loc_80484C1
loc_80484F8
, Intel C++.
1.19.2
strlen() SIMD
( ).
MSVC 2010 /Ox:
128
129
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
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
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.
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.
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.
127
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
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.
, : 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
mov
mov
r11, rdi
rdi, rax
lea
lea
lea
rax, 0[0+r11*4]
r10, [rcx+rax]
r14, [rdx+rax]
.L6:
.L4:
129
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
; store to sum[]
; store to product[]
; store to update_me[]
; reload sum[i]
; reload product[i]
; store to sum_product[]
.L1:
mov
mov
rax, rdi
rdi, r11
mov
mov
mov
add
lea
imul
mov
mov
add
mov
lea
cmp
jne
pop
ret
.L11:
.L10:
; store to update_me[]
; store to sum[]
; store to product[]
; store to sum_product[]
.L7:
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));
};
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:
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
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
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
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
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
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. ++
/ 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
; 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
; sphere::dump, COMDAT
, :
( 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)
;
};
};
; 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"
};
, 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;
};
, :
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
; 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;
};
; 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
??_R1A@?0A@EA@box@@8 DD FLAT:??_R0?AVbox@@@8
DD
01H
DD
00H
DD
0ffffffffH
DD
00H
DD
040H
DD
FLAT:??_R3box@@8
??_R2box@@8 DD
DD
FLAT:??_R1A@?0A@EA@box@@8
FLAT:??_R1A@?0A@EA@object@@8
??_R3box@@8 DD
DD
DD
DD
00H
00H
02H
FLAT:??_R2box@@8
??_R4box@@6B@ DD 00H
DD
00H
DD
00H
DD
FLAT:??_R0?AVbox@@@8
DD
FLAT:??_R3box@@8
??_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
++, .
ostream. operator ostream:
Listing 2.11: MSVC 2012 (reduced listing)
$SG37112 DB
_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";
}
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
(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
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
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. ++
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
; 00000010H
; 00000010H
; 0000000fH
; 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
call
_ZNSsC1EPKcRKSaIcE
mov
mov
call
_ZNSsC1ERKSs
mov
mov
call
_ZNSs6appendERKSs
; inlined c_str():
mov
eax, DWORD PTR [esp+28]
mov
DWORD PTR [esp], eax
call
puts
mov
lea
mov
sub
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());
};
a string, 00H
%s, 0aH, 00H
_main
??__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
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:
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
x=3
x=1
x=5
x=5
y=4
y=2
y=6
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
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
_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
mov
lea
mov
add
mov
loc_80001BD:
loc_80001CF:
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:
locret_80002B8:
main
eax, 0
esp, [ebp-0Ch]
ebx
esi
edi
ebp
; DATA XREF: .eh_frame:08000510
; .eh_frame:080005BC
retn
endp
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>
171
2.4. STL
2. ++
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);
};
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
, 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
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. ++
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.
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. -
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
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);
};
main
PROC
sub
rsp, 72
mov
mov
mov
mov
mov
mov
mov
call
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
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
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
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:
3.4.6
float, double
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
...
.text:000576C0 sub_576C0
proc near
...
.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
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;
};
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]
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
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]
<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
3.5.1
Windows
AMD64
187
3.6
3. -
, . , .
, 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
<stdio.h>
<stdarg.h>
<stdlib.h>
<stdbool.h>
<unistd.h>
<dlfcn.h>
<string.h>
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,
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
190
3.8. ITANIUM
3. -
Listing 3.10: Linux kernel 3.2.0.4
#define TEA_ROUNDS
#define TEA_DELTA
32
0x9e3779b9
=
=
=
=
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
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
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
...
; 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
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
4.1.2
tracer: -
, 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:
, . , , , . , 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
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
; 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
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
fstp
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.
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
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
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
. magic number
.
tracer 6.0.1 , MS-DOS DosBox, heavydebug,
30 ,
DOS.
4.8
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 .
/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]
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
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.
mscoree.dll!_CorExeMain
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.2.1
5.
Linux
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
section .data
msg
len
db Hello, world!,0xa
equ $ - msg
:
nasm -f elf32 1.s
ld 1.o
5.2.2
Windows
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
=
=
=
=
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
... 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.
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
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
...
check1:
: 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
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
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
loc_1186F8:
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
%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
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
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:
2C 00 00 0B
41 82 00 08
48 00 01 80
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
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
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
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:
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
lwz
addi
li
li
li
bl
nop
clrlwi. %r0, %r3, 16
beq
loc_1189AC
li
%r3, 0
b
exit
# --------------------------------------------------------------------------loc_1189AC:
57 A0 06 3E
%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
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
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
38 60 00 01
48 00 00 08
38 60 00 00
%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
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
, ,
.
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
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
push
lea
push
call
add
test
mov
jge
loc_22B48:
loc_22B57:
loc_22B6B:
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
loc_22BDA:
, - .
- 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
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
7.1.
7.
.data:004016A8
dd offset a53
; "53"
dd offset a3c
...
.data:004016B8 _3C_or_3E
.data:004016B8
.data:004016BC
dd offset a3e
...
.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
inc
xor
mov
cmp
jle
ds:ctl_port
eax, eax
al, ds:ctl_port
eax, edi
short loc_D652
loc_D67B:
loc_D6C0:
loc_D6D1:
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
.
. . ( - 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
=
=
=
=
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
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
=
=
=
=
=
=
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
mov
mov
cmp
jnz
lea
push
call
add
push
50h
loc_A453:
loc_A466:
loc_A481:
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
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
inc
cmp
jle
mov
test
jz
edi
edi, 3
short loc_DA55
eax, ds:net_env
eax, eax
short error
mov
mov
loc_DA83:
loc_DA9F:
loc_DAB0:
...
.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
sp
_out_port ; 0x378
[bp+arg_0]
al
( ).
out_port() -:
seg030:0041
seg030:0041
sent_pro
proc far
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
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
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
si, 4
shl
mov
in
test
jnz
or
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+
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
push
call
pop
push
push
call
pop
mov
shl
mov
dec
jnz
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
loc_35A85:
8A 5E FD
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
loc_35A90:
8B 16 82 E7
8A C3
EE
8B C7
5F
5E
C9
CB
sent_pro
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)
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
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
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
ax, ax
pop
leave
retf
endp
si
loc_35B0C:
5E
C9
CB
check_dongle
- , ,
, - ( - -
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
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
=
=
=
=
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
; --------------------------------------------------------------------------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
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
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
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
; --------------------------------------------------------------------------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
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
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
;
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
; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================
rotate3
proc near
var_40
arg_0
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
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:
loc_541163:
loc_541186:
loc_54118B:
rotate3
; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================
arg_0
arg_4
= 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
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:
loc_541229:
push
call
add
dec
jnz
esi
rotate1
esp, 4
edi
short loc_54123D
loc_54123D:
next_character_in_password:
mov
inc
test
jnz
pop
pop
pop
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:
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
ebx
ebx, [esp+4+arg_0]
ebp
esi
edi
ebp, ebp
; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================
= 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
; --------------------------------------------------------------------------align 10h
; =============== S U B R O U T I N E =======================================
= 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
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 =======================================
= 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:
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
= 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
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
= 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
tolower(), .
.text:005411C7
.text:005411CB
.text:005411CC
.text:005411D1
movsx
push
call
add
, , ! ,
, ,
.
.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:
, , . 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
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
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)
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
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)
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]
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
=
=
=
=
=
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]
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
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
push
call
dword_644F93E8
FEWTraceError
push
push
push
call
add
push
push
eax
offset aCclientStart_6 ; "CClient::Start: set shortcut user to
push
call
add
. . . :
.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
=
=
=
=
=
=
=
push
mov
call
mov
xor
lea
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
263
7.3. SAP
.text:64404FE4
.text:64404FE9
7.
push
mov
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
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]
cmp
jz
push
mov
, , 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
call
xor
push
lea
push
push
push
call
mov
cmp
jle
cdq
sub
sar
mov
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]
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]
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
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
268
7.3. SAP
.text:64406FD0
"...
.text:64406FD5
.text:64406FDA
.text:64406FE0
7.
push
push
push
call
sub_644055C5. memcpy() -
IDA sub_64417440.
sub_64417440. :
.text:6441747C
.text:64417481
.text:64417483
push
call
add
` . ,
Voila!
SAP - MaxDB. .
:
.text:64406F79
.text:64406F80
cmp
jnz
`
JNZ JMP. TDW_NOCOMPRESS. Voila!
Wireshark . , , .
,
.
7.3.2
SAP 6.0
http://www.debuginfo.com/tools/typeinfodump.html
269
7.3. SAP
7.
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
:
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
mov
call
cmp
jz
cmp
jz
xor
mov
call
test
jz
mov
add
pop
pop
pop
pop
pop
retn
, :
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
7.
! .
, , 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
, sapgparam() - . 1768 . , ,
, .
! , Oracle RDBMS. ,
disp+work ++. , ?
7.4
7.4.1
Oracle RDBMS
V$VERSION Oracle RDBMS
:
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
272
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
, , 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
273
7.
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
...
.rodata:08019570
"...
.rodata:08019574
.rodata:08019578
.rodata:0801957C
.rodata:08019580
,0"...
.rodata:08019584
.rodata:08019588
.rodata:0801958C
.rodata:08019590
"...
.rodata:08019594
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
dd offset kqfv199_c_0
dd
dd
dd
dd
6
; DATA XREF: .rodata:08019574
offset _2__STRING_5017_0 ; "BANNER"
0
offset _2__STRING_0_0
274
:
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]
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
http://yurichev.com/oracle_tables.html
275
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
X$VERSION. kqftap:
Listing 7.8: kqf.o
.rodata:08042680
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
proc near
var_7C
var_18
var_14
Dest
var_C
var_8
var_4
arg_8
arg_C
arg_14
arg_18
=
=
=
=
=
=
=
=
=
=
=
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.
; 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:
loc_2CE1192:
277
7.
loc_2CE11A8:
loc_2CE122B:
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.
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:
mov
mov
mov
mov
mov
edx,
esi,
edi,
eax,
ebx,
mov
test
jz
push
push
mov
push
push
call
add
loc_2CE1288:
loc_2CE12A7:
_kqvrow_
eax, eax
esp, ebp
ebp
; EAX=0
, . - ,
:
1
2
3
4
5
- .
7.4.2
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.
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
http://yurichev.com/oracle_tables.html
280
7.4.3
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.
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
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
proc near
var_1C
arg_4
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.
6.0.1
"8.
"
"8.
"
"8.
"
".}..
"
, 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
66h
ebp
ebp, esp
eax, [ebp+8]
dword ptr [eax], 0
ds:__imp__GetTickCount@0 ; GetTickCount()
edx, eax
283
_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]
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
; 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
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
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
; 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
, - 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
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:
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
292
10.
10
, , :
1) ? .
2) /++.
.
10.1
10.1.1
1.1
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
r1,r0,#0x61
r1,#0x19
r0,r0,#0x20
r0,r0,#0xff
lr
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
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
{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}
{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
bss
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|
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
{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|
{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
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
{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
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
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
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|
{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
{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|
{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
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
loc_8048433:
313
10.2.
loc_804846D:
10.
mov
mov
mov
mov
inc
cmp
jnz
push
push
mov
push
push
call
mov
add
test
jns
mov
xor
movzx
mov
mov
mov
mov
inc
cmp
jnz
push
push
mov
push
push
call
add
mov
test
jns
xor
mov
mov
mov
mov
inc
cmp
jnz
loc_8048482:
loc_80484AB:
loc_80484E1:
loc_80484F6:
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
push
push
mov
push
push
call
add
mov
test
js
cmp
jnb
xor
mov
loc_8048537:
loc_804855F:
loc_8048588:
ebx, edi
loc_8048513
mov
sub
cmp
ja
mov
mov
sub
cmp
ja
sub
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:
mov
mov
cmp
ja
mov
mov
mov
add
dec
imul
add
cmp
mov
jbe
mov
loc_804862E:
loc_8048634:
loc_804864C:
loc_804866B:
316
10.2.
10.
add
edx, ebx
cmp
jbe
cmp
jz
xor
loc_80486A3:
loc_80486B2:
edx, edi
loc_80486D5:
mov
add
mov
sub
cmp
jbe
mov
mov
mov
loc_8048733:
317
10.2.
dec
10.
[ebp+var_11C]
loc_804875B:
edi, ebx
edi
ecx, [edi-1]
[ebp+var_134], ecx
loc_804876F:
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
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.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
10.3
crackme / keygenme
keygenme:
http://crackmes.de/users/yonkie/
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;
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.
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;
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,
322
11.1.
11.
11.1.8
1.8
100
200
11.1.9
1.9
100
200
300
11.1.10
1.11
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
11.5.2
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
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)
0
0.
.
.
,
.
.
CLI/STI
/
REP MOVSx, REP CMPSx, REP LODSx, REP SCASx.
CLD/STD
/
.
.
,
CPU DRx.
11.5.3
FPU-
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 +
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)
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
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
; size = 4
; size = 4
eax, DWORD PTR _b$[esp-4]
ecx, DWORD PTR _a$[esp-4]
eax, DWORD PTR [eax+ecx*8]
0
. : http://en.wikipedia.org/wiki/Addressing_mode
335
11.5. X86
int f1(int a)
{
return a*13;
};
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
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
11.5. X86
(, 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
; 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
;
;
;
;
;
;
;
;
;
;
clear direction
(esi) -> first block to compare
(edi) -> second block to compare
mov
shr
jz
repe
jnz
ecx,RcmLength
ecx,2
rcm20
cmpsd
rcm40
rcm20:
;
;
;
esi,RcmSource1
edi,RcmSource2
;
;
;
;
;
rcm10:
;
;
;
esi
edi
mov
and
jz
repe
jnz
ecx,RcmLength
ecx,3
rcm30
cmpsb
rcm50
rcm30:
mov
pop
pop
stdRET
eax,RcmLength
edi
esi
_RtlCompareMemory
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
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
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)
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
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
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
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