forked from wangyif2/RE-for-beginners
-
Notifications
You must be signed in to change notification settings - Fork 0
/
signed_numbers.tex
executable file
·112 lines (103 loc) · 6.8 KB
/
signed_numbers.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
\section{\SignedNumbersSectionName}
\label{sec:signednumbers}
\index{Signed numbers}
\newcommand{\URLS}{\url{http://en.wikipedia.org/wiki/Signed_number_representations}}
\IFRU
{Методов представления чисел с знаком ``плюс'' или ``минус'' несколько\footnote{\URLS},
а в x86 применяется метод ``дополнительный код'' или ``two's complement''.}
{There are several methods of representing signed numbers\footnote{\URLS},
but in x86 architecture used ``two's complement''.}
\begin{center}
\begin{tabular}{ | l | l | l | l | }
\hline
\cellcolor{blue!25} \IFRU{двоичное}{binary} &
\cellcolor{blue!25} \IFRU{шестнадцатеричное}{hexadecimal} &
\cellcolor{blue!25} \IFRU{беззнаковое}{unsigned} &
\cellcolor{blue!25} \IFRU{знаковое}{signed} (\IFRU{дополнительный код}{2's complement}) \\
\hline
01111111 & 0x7f & 127 & 127 \\
\hline
01111110 & 0x7e & 126 & 126 \\
\hline
\multicolumn{4}{ |c| }{...} \\
\hline
00000010 & 0x2 & 2 & 2 \\
\hline
00000001 & 0x1 & 1 & 1 \\
\hline
00000000 & 0x0 & 0 & 0 \\
\hline
11111111 & 0xff & 255 & -1 \\
\hline
11111110 & 0xfe & 254 & -2 \\
\hline
\multicolumn{4}{ |c| }{...} \\
\hline
10000010 & 0x82 & 130 & -126 \\
\hline
10000001 & 0x81 & 129 & -127 \\
\hline
10000000 & 0x80 & 128 & -128 \\
\hline
\end{tabular}
\end{center}
\index{x86!\Instructions!JA}
\index{x86!\Instructions!JB}
\index{x86!\Instructions!JL}
\index{x86!\Instructions!JG}
\IFRU{Разница в подходе к знаковым/беззнаковым числам, собственно, нужна потому что, например,
если представить \TT{0xFFFFFFFE} и \TT{0x0000002} как беззнаковое, то первое число ($4294967294$) больше второго ($2$).
Если их оба представить как знаковые, то первое будет $-2$, которое, разумеется, меньше чем второе ($2$).
Вот почему инструкции для условных переходов~(\ref{sec:Jcc}) представлены в обоих версиях ~---
и для знаковых сравнений (например \JG, \JL) и для беззнаковых (\JA, \JB).}
{The difference between signed and unsigned numbers is that if we represent \TT{0xFFFFFFFE} and \TT{0x0000002}
as unsigned, then first number ($4294967294$) is bigger than second ($2$).
If to represent them both as signed, first will be $-2$, and it is lesser than second ($2$).
That is the reason why conditional jumps~(\ref{sec:Jcc}) are present both for signed (e.g. \JG, \JL)
and unsigned (\JA, \JB) operations.} \\
\\
\IFRU{Для простоты, вот что нужно знать}{For the sake of simplicity, that is what one need to know}:
\begin{itemize}
\item \IFRU{Числа бывают знаковые и беззнаковые}{Number can be signed or unsigned}.
\item \IFRU{Знаковые типы в \CCpp}{\CCpp signed types}:
\TT{int} (-2147483646..2147483647 \OrENRU \TT{0x80000000..0x7FFFFFFF}),
\TT{char} (-127..128 \OrENRU \TT{0x7F..0x80}).
\IFRU{Беззнаковые}{Unsigned}: \TT{unsigned int} (0..4294967295 \OrENRU \TT{0..0xFFFFFFFF}),
\TT{unsigned char} (0..255 \OrENRU \TT{0..0xFF}),
\TT{size\_t}.
\item \IFRU{У знаковых чисел знак определяется самым старшим битом: 1 означает ``минус'', 0 означает ``плюс''}
{Signed types has sign in the most significant bit: 1 mean ``minus'', 0 mean ``plus''}.
\item \IFRU{Инструкции сложения и вычитания работают одинаково хорошо и для знаковых и для беззнаковых значений}
{Addition and subtraction operations are working well for both signed and unsigned values}.
\IFRU{Но для операций умножения и деления, в x86 имеются разные инструкции}
{But for multiplication and division operations, x86 has different instructions}:
\TT{IDIV}/\TT{IMUL} \IFRU{для знаковых}{for signed}
\AndENRU \TT{DIV}/\TT{MUL} \IFRU{для беззнаковых}{for unsigned}.
\item \IFRU{Еще инструкции работающие с знаковыми числами}{More instructions working with signed numbers}:
\TT{CBW/CWD/CWDE/CDQ/CDQE} (\ref{ins:CBW_CWD_etc}), \TT{MOVSX} (\ref{MOVSX}), \TT{SAR} (\ref{ins:SAR}).
\end{itemize}
\subsection{\IFRU{Переполнение integer}{Integer overflow}}
\IFRU{Бывает так, что ошибки представления знаковых/беззнаковых могут привести к уязвимости
\IT{переполнение integer}.}
{It is worth noting that incorrect representation of number can lead integer overflow vulnerability.}
\IFRU{Например, есть некий сервис, который принимает по сети некие пакеты.
В пакете есть заголовок где указана длина пакета. Это 32-битное значение.
В процессе приема пакета,
сервис проверяет это значение и сверяет, больше ли оно чем максимальный размер пакета, скажем, константа
\TT{MAX\_PACKET\_SIZE} (например, 10 килобайт), и если да, то пакет отвергается как некорректный.
Сравнение знаковое. Злоумышленник подставляет значение \TT{0xFFFFFFFF}. Это число трактуется как знаковое $-1$
и оно меньше чем $10000$. Проверка проходит. Продолжаем дальше и копируем этот пакет куда-нибудь себе
в сегмент данных\dots вызов функции \TT{memcpy (dst, src, 0xFFFFFFFF)} скорее всего,
затрет много чего внутри процесса.}
{For example, we have a network service, it receives network packets.
In the packets there is also a field where subpacket length is coded.
It is 32-bit value.
After network packet received, service checking the field, and if it is larger than,
e.g. some \TT{MAX\_PACKET\_SIZE} (let's say, 10 kilobytes), the packet is rejected as incorrect.
Comparison is signed. Intruder set this value to the \TT{0xFFFFFFFF}.
While comparison, this number is considered as signed $-1$ and it is lesser than 10 kilobytes.
No error here.
Service would like to copy the subpacket to another place in memory and call
\TT{memcpy (dst, src, 0xFFFFFFFF)} function: this operation, rapidly garbling a lot of
inside of process memory.}
\IFRU{Немного подробнее}{More about it}: \cite{Phrack3C0A}.