100% found this document useful (2 votes)
11 views

(Ebook) Foundations of Linux Debugging, Disassembling, and Reversing: Analyze Binary Code, Understand Stack Memory Usage, and Reconstruct C/C++ Code with Intel x64 by Dmitry Vostokov ISBN 9781484291528, 1484291522 - Read the ebook now with the complete version and no limits

The document promotes instant access to various eBooks available for download at ebooknice.com, including titles on Linux and ARM64 debugging, cooking, mathematics, and SAT preparation. Each eBook entry includes the title, author, ISBN, and a direct link for purchase. The document emphasizes the convenience of digital formats and the ability to read on any device.

Uploaded by

bleidyyabuta
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
11 views

(Ebook) Foundations of Linux Debugging, Disassembling, and Reversing: Analyze Binary Code, Understand Stack Memory Usage, and Reconstruct C/C++ Code with Intel x64 by Dmitry Vostokov ISBN 9781484291528, 1484291522 - Read the ebook now with the complete version and no limits

The document promotes instant access to various eBooks available for download at ebooknice.com, including titles on Linux and ARM64 debugging, cooking, mathematics, and SAT preparation. Each eBook entry includes the title, author, ISBN, and a direct link for purchase. The document emphasizes the convenience of digital formats and the ability to read on any device.

Uploaded by

bleidyyabuta
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 73

Instant Ebook Access, One Click Away – Begin at ebooknice.

com

(Ebook) Foundations of Linux Debugging,


Disassembling, and Reversing: Analyze Binary Code,
Understand Stack Memory Usage, and Reconstruct
C/C++ Code with Intel x64 by Dmitry Vostokov ISBN
9781484291528, 1484291522
https://ebooknice.com/product/foundations-of-linux-
debugging-disassembling-and-reversing-analyze-binary-code-
understand-stack-memory-usage-and-reconstruct-c-c-code-with-
intel-x64-47633766

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebooknice.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Start reading on any device today!

(Ebook) Foundations of ARM64 Linux Debugging, Disassembling, and Reversing: Analyze


Code, Understand Stack Memory Usage, and Reconstruct Original C/C++ Code with ARM64
by Dmitry Vostokov ISBN 9781484290811, 148429081X

https://ebooknice.com/product/foundations-of-arm64-linux-debugging-
disassembling-and-reversing-analyze-code-understand-stack-memory-usage-and-
reconstruct-original-c-c-code-with-arm64-47632832

ebooknice.com

(Ebook) Biota Grow 2C gather 2C cook by Loucas, Jason; Viles, James ISBN
9781459699816, 9781743365571, 9781925268492, 1459699815, 1743365578, 1925268497

https://ebooknice.com/product/biota-grow-2c-gather-2c-cook-6661374

ebooknice.com

(Ebook) Matematik 5000+ Kurs 2c Lärobok by Lena Alfredsson, Hans Heikne, Sanna
Bodemyr ISBN 9789127456600, 9127456609

https://ebooknice.com/product/matematik-5000-kurs-2c-larobok-23848312

ebooknice.com

(Ebook) SAT II Success MATH 1C and 2C 2002 (Peterson's SAT II Success) by Peterson's
ISBN 9780768906677, 0768906679

https://ebooknice.com/product/sat-ii-success-math-1c-and-2c-2002-peterson-s-sat-
ii-success-1722018

ebooknice.com
(Ebook) Master SAT II Math 1c and 2c 4th ed (Arco Master the SAT Subject Test: Math
Levels 1 & 2) by Arco ISBN 9780768923049, 0768923042

https://ebooknice.com/product/master-sat-ii-math-1c-and-2c-4th-ed-arco-master-
the-sat-subject-test-math-levels-1-2-2326094

ebooknice.com

(Ebook) Cambridge IGCSE and O Level History Workbook 2C - Depth Study: the United
States, 1919-41 2nd Edition by Benjamin Harrison ISBN 9781398375147, 9781398375048,
1398375144, 1398375047

https://ebooknice.com/product/cambridge-igcse-and-o-level-history-
workbook-2c-depth-study-the-united-states-1919-41-2nd-edition-53538044

ebooknice.com

(Ebook) Accelerated Disassembly, Reconstruction and Reversing, Second Revised


Edition by Dmitry Vostokov ISBN 9781912636693, 1912636697

https://ebooknice.com/product/accelerated-disassembly-reconstruction-and-
reversing-second-revised-edition-52237588

ebooknice.com

(Ebook) Python Debugging for AI, Machine Learning, and Cloud Computing by Dmitry
Vostokov ISBN 9781484297452, 1484297458

https://ebooknice.com/product/python-debugging-for-ai-machine-learning-and-
cloud-computing-55714196

ebooknice.com

(Ebook) Advanced Windows Memory Dump Analysis with Data Structures by Dmitry
Vostokov ISBN 9781908043849, 1908043849

https://ebooknice.com/product/advanced-windows-memory-dump-analysis-with-data-
structures-6621088

ebooknice.com
Foundations of Linux
Debugging, Disassembling,
and Reversing
Analyze Binary Code, Understand
Stack Memory Usage, and Reconstruct
C/C++ Code with Intel x64

Dmitry Vostokov
Foundations of Linux
Debugging,
Disassembling, and
Reversing
Analyze Binary Code,
Understand Stack Memory
Usage, and Reconstruct C/C++
Code with Intel x64

Dmitry Vostokov
Foundations of Linux Debugging, Disassembling, and Reversing: Analyze
Binary Code, Understand Stack Memory Usage, and Reconstruct C/C++
Code with Intel x64
Dmitry Vostokov
Dublin, Ireland

ISBN-13 (pbk): 978-1-4842-9152-8 ISBN-13 (electronic): 978-1-4842-9153-5


https://doi.org/10.1007/978-1-4842-9153-5

Copyright © 2023 by Dmitry Vostokov


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or
part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way,
and transmission or information storage and retrieval, electronic adaptation, computer software,
or by similar or dissimilar methodology now known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark
symbol with every occurrence of a trademarked name, logo, or image we use the names, logos,
and images only in an editorial fashion and to the benefit of the trademark owner, with no
intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if
they are not identified as such, is not to be taken as an expression of opinion as to whether or not
they are subject to proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of
publication, neither the authors nor the editors nor the publisher can accept any legal
responsibility for any errors or omissions that may be made. The publisher makes no warranty,
express or implied, with respect to the material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Celestin Suresh John
Development Editor: James Markham
Coordinating Editor: Mark Powers
Cover designed by eStudioCalamar
Cover image by Eugene Golovesov on Unsplash (www.unsplash.com)
Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY
10004, U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected],
or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member
(owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance
Inc is a Delaware corporation.
For information on translations, please e-mail [email protected]; for
reprint, paperback, or audio rights, please e-mail [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook
versions and licenses are also available for most titles. For more information, reference our Print
and eBook Bulk Sales web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is
available to readers on GitHub (https://github.com/Apress). For more detailed information,
please visit http://www.apress.com/source-code.
Printed on acid-free paper
Table of Contents
About the Author���������������������������������������������������������������������������������ix

About the Technical Reviewer�������������������������������������������������������������xi

Preface����������������������������������������������������������������������������������������������xiii

Chapter 1: Memory, Registers, and Simple Arithmetic�������������������������1


Memory and Registers Inside an Idealized Computer������������������������������������������1
Memory and Registers Inside Intel 64-Bit PC�������������������������������������������������������2
“Arithmetic” Project: Memory Layout and Registers��������������������������������������������3
“Arithmetic” Project: A Computer Program�����������������������������������������������������������5
“Arithmetic” Project: Assigning Numbers to Memory Locations���������������������������5
Assigning Numbers to Registers���������������������������������������������������������������������������8
“Arithmetic” Project: Adding Numbers to Memory Cells���������������������������������������8
Incrementing/Decrementing Numbers in Memory and Registers�����������������������11
Multiplying Numbers�������������������������������������������������������������������������������������������14
Summary������������������������������������������������������������������������������������������������������������17

Chapter 2: Code Optimization�������������������������������������������������������������19


“Arithmetic” Project: C/C++ Program�����������������������������������������������������������������19
Downloading GDB�����������������������������������������������������������������������������������������������20
GDB Disassembly Output – No Optimization�������������������������������������������������������20
GDB Disassembly Output – Optimization������������������������������������������������������������25
Summary������������������������������������������������������������������������������������������������������������26

iii
Table of Contents

Chapter 3: Number Representations��������������������������������������������������27


Numbers and Their Representations�������������������������������������������������������������������27
Decimal Representation (Base Ten)��������������������������������������������������������������������28
Ternary Representation (Base Three)������������������������������������������������������������������29
Binary Representation (Base Two)����������������������������������������������������������������������29
Hexadecimal Representation (Base Sixteen)������������������������������������������������������30
Why Are Hexadecimals Used?�����������������������������������������������������������������������������30
Summary������������������������������������������������������������������������������������������������������������32

Chapter 4: Pointers�����������������������������������������������������������������������������33
A Definition���������������������������������������������������������������������������������������������������������33
“Pointers” Project: Memory Layout and Registers����������������������������������������������34
“Pointers” Project: Calculations��������������������������������������������������������������������������36
Using Pointers to Assign Numbers to Memory Cells�������������������������������������������36
Adding Numbers Using Pointers�������������������������������������������������������������������������42
Incrementing Numbers Using Pointers���������������������������������������������������������������45
Multiplying Numbers Using Pointers�������������������������������������������������������������������48
Summary������������������������������������������������������������������������������������������������������������51

Chapter 5: Bytes, Words, Double, and Quad Words�����������������������������53


Using Hexadecimal Numbers������������������������������������������������������������������������������53
Byte Granularity��������������������������������������������������������������������������������������������������53
Bit Granularity�����������������������������������������������������������������������������������������������������54
Memory Layout���������������������������������������������������������������������������������������������������55
Summary������������������������������������������������������������������������������������������������������������58

Chapter 6: Pointers to Memory�����������������������������������������������������������59


Pointers Revisited�����������������������������������������������������������������������������������������������59
Addressing Types������������������������������������������������������������������������������������������������59

iv
Table of Contents

Registers Revisited���������������������������������������������������������������������������������������������65
NULL Pointers�����������������������������������������������������������������������������������������������������65
Invalid Pointers���������������������������������������������������������������������������������������������������65
Variables As Pointers������������������������������������������������������������������������������������������66
Pointer Initialization��������������������������������������������������������������������������������������������67
Initialized and Uninitialized Data�������������������������������������������������������������������������67
More Pseudo Notation�����������������������������������������������������������������������������������������68
“MemoryPointers” Project: Memory Layout�������������������������������������������������������68
Summary������������������������������������������������������������������������������������������������������������79

Chapter 7: Logical Instructions and RIP���������������������������������������������81


Instruction Format����������������������������������������������������������������������������������������������81
Logical Shift Instructions������������������������������������������������������������������������������������82
Logical Operations����������������������������������������������������������������������������������������������82
Zeroing Memory or Registers�����������������������������������������������������������������������������83
Instruction Pointer�����������������������������������������������������������������������������������������������84
Code Section�������������������������������������������������������������������������������������������������������85
Summary������������������������������������������������������������������������������������������������������������86

Chapter 8: Reconstructing a Program with Pointers��������������������������87


Example of Disassembly Output: No Optimization����������������������������������������������87
Reconstructing C/C++ Code: Part 1��������������������������������������������������������������������90
Reconstructing C/C++ Code: Part 2��������������������������������������������������������������������92
Reconstructing C/C++ Code: Part 3��������������������������������������������������������������������93
Reconstructing C/C++ Code: C/C++ Program����������������������������������������������������94
Example of Disassembly Output: Optimized Program�����������������������������������������95
Summary������������������������������������������������������������������������������������������������������������96

v
Table of Contents

Chapter 9: Memory and Stacks����������������������������������������������������������97


Stack: A Definition�����������������������������������������������������������������������������������������������97
Stack Implementation in Memory�����������������������������������������������������������������������98
Things to Remember�����������������������������������������������������������������������������������������100
PUSH Instruction�����������������������������������������������������������������������������������������������101
POP Instruction�������������������������������������������������������������������������������������������������101
Register Review������������������������������������������������������������������������������������������������102
Application Memory Simplified�������������������������������������������������������������������������105
Stack Overflow��������������������������������������������������������������������������������������������������105
Jumps���������������������������������������������������������������������������������������������������������������106
Calls������������������������������������������������������������������������������������������������������������������108
Call Stack����������������������������������������������������������������������������������������������������������110
Exploring Stack in GDB�������������������������������������������������������������������������������������112
Summary����������������������������������������������������������������������������������������������������������115

Chapter 10: Frame Pointer and Local Variables�������������������������������117


Stack Usage������������������������������������������������������������������������������������������������������117
Register Review������������������������������������������������������������������������������������������������118
Addressing Array Elements�������������������������������������������������������������������������������118
Stack Structure (No Function Parameters)�������������������������������������������������������119
Function Prolog�������������������������������������������������������������������������������������������������121
Raw Stack (No Local Variables and Function Parameters)�������������������������������121
Function Epilog�������������������������������������������������������������������������������������������������123
“Local Variables” Project����������������������������������������������������������������������������������124
Disassembly of Optimized Executable��������������������������������������������������������������127
Summary����������������������������������������������������������������������������������������������������������128

vi
Table of Contents

Chapter 11: Function Parameters�����������������������������������������������������129


“FunctionParameters” Project��������������������������������������������������������������������������129
Stack Structure�������������������������������������������������������������������������������������������������130
Function Prolog and Epilog�������������������������������������������������������������������������������132
Project Disassembled Code with Comments����������������������������������������������������133
Parameter Mismatch Problem��������������������������������������������������������������������������137
Summary����������������������������������������������������������������������������������������������������������138

Chapter 12: More Instructions����������������������������������������������������������139


CPU Flags Register��������������������������������������������������������������������������������������������139
The Fast Way to Fill Memory�����������������������������������������������������������������������������140
Testing for 0������������������������������������������������������������������������������������������������������141
TEST – Logical Compare�����������������������������������������������������������������������������������142
CMP – Compare Two Operands�������������������������������������������������������������������������143
TEST or CMP?���������������������������������������������������������������������������������������������������144
Conditional Jumps��������������������������������������������������������������������������������������������144
The Structure of Registers��������������������������������������������������������������������������������145
Function Return Value���������������������������������������������������������������������������������������146
Using Byte Registers�����������������������������������������������������������������������������������������146
Summary����������������������������������������������������������������������������������������������������������147

Chapter 13: Function Pointer Parameters����������������������������������������149


“FunctionPointerParameters” Project���������������������������������������������������������������149
Commented Disassembly���������������������������������������������������������������������������������150
Summary����������������������������������������������������������������������������������������������������������159

vii
Table of Contents

Chapter 14: Summary of Code Disassembly Patterns����������������������161


Function Prolog/Epilog��������������������������������������������������������������������������������������161
LEA (Load Effective Address)����������������������������������������������������������������������������164
Passing Parameters������������������������������������������������������������������������������������������164
Accessing Parameters and Local Variables������������������������������������������������������165
Summary����������������������������������������������������������������������������������������������������������166

Index�������������������������������������������������������������������������������������������������167

viii
About the Author
Dmitry Vostokov is an internationally
recognized expert, speaker, educator, scientist,
and author. He is the founder of the pattern-
oriented software diagnostics, forensics,
and prognostics discipline and Software
Diagnostics Institute (DA+TA: DumpAnalysis.
org + TraceAnalysis.org). Vostokov has also
authored more than 50 books on software
diagnostics, anomaly detection and analysis,
software and memory forensics, root cause analysis and problem solving,
memory dump analysis, debugging, software trace and log analysis,
reverse engineering, and malware analysis. He has more than 25 years
of experience in software architecture, design, development, and
maintenance in various industries, including leadership, technical, and
people management roles. Dmitry also founded Syndromatix, Anolog.
io, BriteTrace, DiaThings, Logtellect, OpenTask Iterative and Incremental
Publishing (OpenTask.com), Software Diagnostics Technology and
Services (former Memory Dump Analysis Services; PatternDiagnostics.
com), and Software Prognostics. In his spare time, he presents various
topics on Debugging TV and explores Software Narratology, its further
development as Narratology of Things and Diagnostics of Things (DoT),
and Software Pathology. His current areas of interest are theoretical
software diagnostics and its mathematical and computer science
foundations, application of artificial intelligence, machine learning and

ix
About the Author

data mining to diagnostics and anomaly detection, software diagnostics


engineering and diagnostics-driven development, and diagnostics
workflow and interaction. Recent areas of interest also include cloud
native computing, security, automation, functional programming, and
applications of category theory to software development and big data.

x
About the Technical Reviewer
Vikas Talan is a senior engineer at Qualcomm
(an American multinational corporation). He is
the founder of S.M.A.R.T Solutions, a technical
company. He also worked at MediaTek and
Cadence in core technical domains. He has
in-depth experience in Linux kernel
programming, Linux device drivers, ARM 64,
ARM, and porting of Android OS and Linux
drivers on chipsets. He hails from Delhi
NCR, India.

xi
Preface
The book covers topics ranging from Intel x64 assembly language
instructions and writing programs in assembly language to pointers, live
debugging, and static binary analysis of compiled C and C++ code.
Diagnostics of core memory dumps, live and postmortem debugging
of Linux applications, services, and systems, memory forensics, malware,
and vulnerability analysis require an understanding of x64 Intel assembly
language and how C and C++ compilers generate code, including
memory layout and pointers. This book is about background knowledge
and practical foundations that are needed to understand internal Linux
program structure and behavior, start working with the GDB debugger, and
use it for disassembly and reversing. It consists of practical step-by-step
exercises of increasing complexity with explanations and many diagrams,
including some necessary background topics.
By the end of the book, you will have a solid understanding of how
Linux C and C++ compilers generate binary code. In addition, you will be
able to analyze such code confidently, understand stack memory usage,
and reconstruct original C/C++ code.
The book will be useful for

• Software technical support and escalation engineers

• Software engineers coming from JVM background

• Software testers

• Engineers coming from non-Linux environments, for


example, Windows or Mac OS X

xiii
Preface

• Linux C/C++ software engineers without assembly


language background

• Security researchers without assembly language


background

• Beginners learning Linux software reverse engineering


techniques

This book can also be used as an x64 assembly language and Linux
debugging supplement for relevant undergraduate-level courses.

Source Code
All source code used in this book can be downloaded from github.com/
apress/linux-debugging-disassembling-reversing.

xiv
CHAPTER 1

Memory, Registers,
and Simple Arithmetic
 emory and Registers Inside
M
an Idealized Computer
Computer memory consists of a sequence of memory cells, and each cell
has a unique address (location). Every cell contains a “number.” We refer
to these “numbers” as contents at addresses (locations). Because memory
access is slower than arithmetic instructions, there are so-called registers
to speed up complex operations that require memory to store temporary
results. We can also think about them as stand-alone memory cells. The
name of a register is its address. Figure 1-1 illustrates this concept.

© Dmitry Vostokov 2023 1


D. Vostokov, Foundations of Linux Debugging, Disassembling, and Reversing,
https://doi.org/10.1007/978-1-4842-9153-5_1
Chapter 1 Memory, Registers, and Simple Arithmetic

Figure 1-1. Computer memory represented as a sequence of memory


cells and locations

 emory and Registers Inside Intel


M
64-Bit PC
Figure 1-2 shows addresses for memory locations containing integer
values usually differ by four or eight, and we also show two registers called
%RAX and %RDX. The first halves of them are called %EAX and %EDX.

2
Chapter 1 Memory, Registers, and Simple Arithmetic

Figure 1-2. Typical Intel x64 memory and register layout

Because memory cells contain “numbers,” we start with simple


arithmetic and ask a PC to compute the sum of two numbers to see how
memory and registers change their values.

“ Arithmetic” Project: Memory Layout


and Registers
For our project, we have two memory addresses (locations) that we call
“a” and “b.” We can think about “a” and “b” as names of their respective
addresses (locations). Now we introduce a special notation where (a) means

3
Chapter 1 Memory, Registers, and Simple Arithmetic

contents at the memory address (location) “a.” If we use the C or C++


language to write our project, we declare and define memory locations “a”
and “b” as

static int a, b;

By default, when we load a program, static memory locations are filled


with zeroes, and we can depict our initial memory layout after loading the
program, as shown in Figure 1-3.

Figure 1-3. Initial memory layout after loading the program

4
Chapter 1 Memory, Registers, and Simple Arithmetic

“Arithmetic” Project: A Computer Program


We can think of a computer program as a sequence of instructions for
the manipulation of contents of memory cells and registers. For example,
addition operation: add the contents of memory cell №12 to the contents
of memory cell №14. In our pseudo-code, we can write

(14) + (12) -> (14)

Our first program in pseudo-code is shown on the left of the table:

1 -> (a) Here, we put assembly instructions corresponding


1 -> (b) to pseudo-code.
(b) + (a) -> (b)
(a) + 1 -> (a)
(b) * (a) -> (b)

“->” means moving (assigning) the new value to the contents of a


memory location (address). “;” is a comment sign, and the rest of the line is
a comment. “=” shows the current value at a memory location (address).
To remind, a code written in a high-level programming language is
translated to a machine language by a compiler. However, the machine
language can be readable if its digital codes are represented in some
mnemonic system called assembly language. For example, INC a is
increment by one of what is stored at a memory location “a.”

“ Arithmetic” Project: Assigning Numbers


to Memory Locations
We remind that “a” means location (address) of the memory cell, and it is
also the name of the location (address) 000055555555802c (see Figure 1-3).
(a) means the contents (number) stored at the address “a.”

5
Chapter 1 Memory, Registers, and Simple Arithmetic

If we use the C or C++ language, “a” is called “the variable a,” and we
write the assignment as

a = 1;

In the Intel assembly language, we write

mov $1, a

In the GDB disassembly output, we see the following code where the
variable “a” and address are shown in comments:

movl   $0x1,0x2ef2(%rip)        # 0x55555555802c <a>

We show the translation of our pseudo-code into assembly language in


the right column:

1 -> (a)          ; (a) = 1 movl $1, a


1 -> (b)          ; (b) = 1 movl $1, b
(b) + (a) -> (b)
(a) + 1 -> (a)
(b) * (a) -> (b)

Notice movl instructions instead of mov. This is because “a” and “b”
can point to both 32-bit (like %EAX or %EDX registers) and 64-bit memory
cells (like %RAX and %RDX registers). In the registers’ case, it is clear from
their names whether we use 64-bit %RAX or 32-bit %EAX. But in the case
of memory addresses “a” and “b,” it is not clear whether they refer to 64-bit
or 32-bit cells. We use movl to disambiguate and show that we use 32-bit
memory cells that are enough to hold integers from 0 to 4294967295.
0x2ef2(%rip) is how the compiler generates code to calculate the
address “a” instead of specifying it directly. Such code requires less
memory space. We explain this in later chapters.

6
Chapter 1 Memory, Registers, and Simple Arithmetic

Literal constants have the $ prefix, for example, $0x1. The 0x prefix
means the following number is hexadecimal. The leading four zeroes of
the address are also omitted in the comment. We explain such numbers in
Chapter 3. Please also notice that the movement direction is the same in
both the disassembly output and the pseudo-code: from left to right.
After executing the first two assembly language instructions, we have
the memory layout shown in Figure 1-4.

Figure 1-4. Memory layout after executing the first two assembly
language instructions

7
Chapter 1 Memory, Registers, and Simple Arithmetic

Assigning Numbers to Registers


This is similar to memory assignments. We can write in pseudo-code:

1 -> register
(a) -> register

Note that we do not use brackets when we refer to register contents.


The latter instruction means assigning (copying) the number at the
location (address) “a” to a register.
In assembly language, we write

mov  $1, %eax   # 1 is copied to the first half of %RAX


register
mov  $1, %rax   # full contents of %RAX register are
replaced with 1
mov  a, %eax
mov  a, %rax

In the GDB disassembly output, we may see the following code:

mov    $0x0,%eax

“ Arithmetic” Project: Adding Numbers


to Memory Cells
Now let’s look at the following pseudo-code statement in more detail:

(b) + (a) -> (b)

To recall, “a” and “b” mean the names of locations (addresses)


000055555555802c and 0000555555558030, respectively (see Figure 1-4).
(a) and (b) mean contents at addresses “a” and “b,” respectively, simply
some numbers stored there.

8
Chapter 1 Memory, Registers, and Simple Arithmetic

In the C or C++ language, we write the following statement:

b = b + a;
b += a;

In assembly language, we use the instruction ADD. Because of AMD64


and Intel EM64T architecture’s limitations, we cannot use both memory
addresses in one step (instruction), for example, add a, b. We can only use
the add register, b instruction to add the value stored in the register to
the contents of the memory cell b. Recall that a register is like a temporary
memory cell itself here:

(a) -> register


(b) + register -> (b)

Alternatively, we can use two registers:

(a) -> register1


(b) -> register2
register2 + register1 -> register2
register2 -> (b)

In assembly language, we write

mov a, %eax
add %eax, b

or we can add two registers and move the result to the memory cell b:

mov b, %edx
mov a, %eax
add %edx, %eax
mov %eax, b

9
Chapter 1 Memory, Registers, and Simple Arithmetic

In the GDB disassembly output, we may see the following code:

mov    0x2ee6(%rip),%edx        # 0x555555558030 <b>


mov    0x2edc(%rip),%eax        # 0x55555555802c <a>
add    %edx,%eax
mov    %eax,0x2ed8(%rip)        # 0x555555558030 <b>

Now we can translate our pseudo-code into assembly language:

1 -> (a)          ; (a) = 1 movl $1, a


1 -> (b)          ; (b) = 1 movl $1, b
(b) + (a) -> (b)  ; %eax = 1 mov a, %eax
; %edx = 1     mov  b, %edx
; %eax = 2
   add  %edx, %eax
; (b) = 2
   mov %eax, b
(a) + 1 -> (a)
(b) * (a) -> (b)

After the execution of ADD and MOV instructions, we have the


memory layout illustrated in Figure 1-5.

10
Chapter 1 Memory, Registers, and Simple Arithmetic

Figure 1-5. Memory layout after executing ADD and MOV


instructions

Incrementing/Decrementing Numbers
in Memory and Registers
In pseudo-code, it looks simple and means increment (decrement) a
number stored at the location (address) “a”:

(a) + 1 -> (a)


(a) – 1 -> (a)

11
Chapter 1 Memory, Registers, and Simple Arithmetic

In the C or C++ language, we can write this using three possible ways:

a = a + 1;
++a;
a++;
b = b – 1;
--b;
b--;

In assembly language, we use instructions INC and DEC and write

incl    a
inc     %eax
decl    a
dec     %eax

We use incl when we need to specify the 32-bit memory cell. It is


ambiguous when we use “a.” However, using %eax implies using 32-bit
values, so inc is unambiguous.
In the GDB disassembly output, we may see the same instruction:

inc    %eax

or

add    $0x1,%eax   # a compiler may decide to use ADD


instead of INC

12
Chapter 1 Memory, Registers, and Simple Arithmetic

Now we add the assembly language translation of increment:

1 -> (a)          ; (a) = 1 movl $1, a


1 -> (b)          ; (b) = 1 movl $1, b
(b) + (a) -> (b)  ; %eax = 1 mov a, %eax
; %edx = 1 mov  b, %edx
; %eax = 2 add  %edx, %eax
; (b) = 2 mov %eax, b
(a) + 1 -> (a)    ; %eax = 1 mov  a, %eax
; %eax = 2 add  $1, %eax
; (a) = 2 mov  %eax, a
(b) * (a) -> (b)

After the execution of INC or ADD instruction, we have the memory


layout illustrated in Figure 1-6.

13
Chapter 1 Memory, Registers, and Simple Arithmetic

Figure 1-6. Memory layout after the execution of INC or ADD


instruction

Multiplying Numbers
In pseudo-code, we write

(b) * (a) -> (b)

It means that we multiply the number at the location (address) “b” by


the number at the location (address) “a.”
In the C or C++ language, we can write that using two ways:

b =  b * a;
b *= a;

14
Chapter 1 Memory, Registers, and Simple Arithmetic

In assembly language, we use instruction IMUL (Integer MULtiply)


and write

mov  a, %eax
imul b, %eax
mov  %eax, b

The multiplication instruction means (b) * %eax -> %eax, and we


must put the contents of “a” into %EAX. The multiplication result is put
into the register %EAX, and its contents are saved at the location (address)
“b.” Alternatively, we may put all multiplication operands into registers:

mov  a, %eax
mov  b, %edx
imul %edx, %eax
mov  %eax, b

In the GDB disassembly output, we may see the following code:

mov    0x2ec3(%rip),%edx        # 0x555555558030 <b>


mov    0x2eb9(%rip),%eax        # 0x55555555802c <a>
imul   %edx,%eax
mov    %eax,0x2eb4(%rip)        # 0x555555558030 <b>

15
Chapter 1 Memory, Registers, and Simple Arithmetic

Now we add two additional assembly instructions to our pseudo-code


assembly language translation:

1 -> (a)          ; (a) = 1 movl $1, a


1 -> (b)          ; (b) = 1 movl $1, b
(b) + (a) -> (b)  ; %eax = 1 mov a, %eax
; %edx = 1 mov  b, %edx
; %eax = 2 add  %edx, %eax
; (b) = 2 mov %eax, b
(a) + 1 -> (a)    ; %eax = 1 mov  a, %eax
; %eax = 2 add  $1, %eax
; (a) = 2 mov  %eax, a
(b) * (a) -> (b)  ; %edx = 2 mov  b, %edx
; %eax = 2 mov  a, %eax
; %eax = 4 imul %edx, %eax
; (b) = 4 mov  %eax, b

After the execution of IMUL and MOV instructions, we have the


memory layout illustrated in Figure 1-7.

16
Chapter 1 Memory, Registers, and Simple Arithmetic

Figure 1-7. Memory layout after the execution of IMUL and MOV
instructions

Summary
This chapter introduced CPU registers and explained the memory layout
of a simple arithmetic program. We learned basic x64 instructions and
manually translated simple C and C++ code to assembly language.
The next chapter looks at assembly language code produced by a
debugger via disassembling binary code. Then, we reverse it to C and C++
code. We also compare the disassembly output of nonoptimized code to
optimized code.

17
CHAPTER 2

Code Optimization
“Arithmetic” Project: C/C++ Program
Let’s rewrite our “Arithmetic” program in C/C++. Corresponding assembly
language instructions are put in comments:

int a, b;

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


{
      a = 1;               // movl $1, a

      b = 1;               // movl $1, b

      b = b + a;           // mov  a, %eax


                           // mov  b, %edx
                           // add  %edx, %eax
                           // mov  %eax, b

      ++a;                 // mov  a, %eax


                           // add  $1, %eax
                           // mov  %eax, a

© Dmitry Vostokov 2023 19


D. Vostokov, Foundations of Linux Debugging, Disassembling, and Reversing,
https://doi.org/10.1007/978-1-4842-9153-5_2
Chapter 2 Code Optimization

      b = b * a;           // mov  b, %edx


                           // mov  a, %eax
                           // imul %edx, %eax
                           // mov  %eax, b

                           // results: (a) = 2 and (b) = 4


      return 0;
}

Downloading GDB
We used WSL2 and "Debian GNU/Linux 10 (buster)" as a working
environment. We chose Debian because we used it for the “Accelerated
Linux Core Dump Analysis” training course.1 After installing Debian, we
need to install essential build tools and GDB:

sudo apt install build-essential


sudo apt install gdb

You may also need to download git to clone source code:

sudo apt install git


cd ~
git clone github.com/apress/linux-debugging-disassembling-­
reversing .

GDB Disassembly Output – No Optimization


The source code can be downloaded from the following location:
github.com/apress/linux-debugging-disassembling-reversing/
Chapter2/

1
www.dumpanalysis.org/accelerated-linux-core-dump-analysis-book

20
Chapter 2 Code Optimization

If we compile and link the program in no optimization mode (default):

coredump@DESKTOP-IS6V2L0:~/pflddr/x64/Chapter2$ gcc
ArithmeticProjectC.cpp -o ArithmeticProjectC

we get the binary executable module we can load in GDB and inspect
assembly code.
First, we run GDB with the program as a parameter:

coredump@DESKTOP-IS6V2L0:~/pflddr/x64/Chapter2$ gdb ./
ArithmeticProjectC
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/
licenses/gpl.html>
This is free software: you are free to change and
redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources
online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".


Type "apropos word" to search for commands related to "word"...
Reading symbols from ./ArithmeticProjectC...(no debugging
symbols found)...done.
(gdb)

21
Chapter 2 Code Optimization

Next, we put a breakpoint at our main C/C++ function to allow the


program execution to stop at that point and give us a chance to inspect
memory and registers. Symbolic names/function names like "main" can be
used instead of code memory locations:

(gdb) break main


Breakpoint 1 at 0x1129

Then we start execution of the program (let it run). The program then
stops at the previously set breakpoint:

(gdb) run
Starting program: /home/coredump/pflddr/x64/Chapter2/
ArithmeticProjectC

Breakpoint 1, 0x0000555555555129 in main ()

Now we disassemble the main function:

(gdb) disass main


Dump of assembler code for function main:
   0x0000555555555125 <+0>:     push   %rbp
   0x0000555555555126 <+1>:     mov    %rsp,%rbp
=> 0x0000555555555129 <+4>:     mov    %edi,-0x4(%rbp)
   0x000055555555512c <+7>:     mov    %rsi,-0x10(%rbp)
   0x0000555555555130 <+11>:    movl   $0x1,0x2ef2(%rip)        
# 0x55555555802c <a>
   0x000055555555513a <+21>:    movl   $0x1,0x2eec(%rip)        
# 0x555555558030 <b>
   0x0000555555555144 <+31>:    mov    0x2ee6(%rip),%edx        
# 0x555555558030 <b>
   0x000055555555514a <+37>:    mov    0x2edc(%rip),%eax        
# 0x55555555802c <a>
   0x0000555555555150 <+43>:    add    %edx,%eax

22
Chapter 2 Code Optimization

   0x0000555555555152 <+45>:    mov    %eax,0x2ed8(%rip)        
# 0x555555558030 <b>
   0x0000555555555158 <+51>:    mov    0x2ece(%rip),%eax        
# 0x55555555802c <a>
   0x000055555555515e <+57>:    add    $0x1,%eax
   0x0000555555555161 <+60>:    mov    %eax,0x2ec5(%rip)        
# 0x55555555802c <a>
   0x0000555555555167 <+66>:    mov    0x2ec3(%rip),%edx        
# 0x555555558030 <b>
   0x000055555555516d <+72>:    mov    0x2eb9(%rip),%eax        
# 0x55555555802c <a>
   0x0000555555555173 <+78>:    imul   %edx,%eax
   0x0000555555555176 <+81>:    mov    %eax,0x2eb4(%rip)        
# 0x555555558030 <b>
   0x000055555555517c <+87>:    mov    $0x0,%eax
   0x0000555555555181 <+92>:    pop    %rbp
   0x0000555555555182 <+93>:    retq
End of assembler dump.

We repeat the part of the formatted disassembly output here that


corresponds to our C/C++ code:

   0x0000555555555130 <+11>:    movl   $0x1,0x2ef2(%rip)        
# 0x55555555802c <a>
   0x000055555555513a <+21>:    movl   $0x1,0x2eec(%rip)        
# 0x555555558030 <b>
   0x0000555555555144 <+31>:    mov    0x2ee6(%rip),%edx        
# 0x555555558030 <b>
   0x000055555555514a <+37>:    mov    0x2edc(%rip),%eax        
# 0x55555555802c <a>
   0x0000555555555150 <+43>:    add    %edx,%eax

23
Chapter 2 Code Optimization

   0x0000555555555152 <+45>:    mov    %eax,0x2ed8(%rip)        
# 0x555555558030 <b>
   0x0000555555555158 <+51>:    mov    0x2ece(%rip),%eax        
# 0x55555555802c <a>
   0x000055555555515e <+57>:    add    $0x1,%eax
   0x0000555555555161 <+60>:    mov    %eax,0x2ec5(%rip)        
# 0x55555555802c <a>
   0x0000555555555167 <+66>:    mov    0x2ec3(%rip),%edx        
# 0x555555558030 <b>
   0x000055555555516d <+72>:    mov    0x2eb9(%rip),%eax        
# 0x55555555802c <a>
   0x0000555555555173 <+78>:    imul   %edx,%eax
   0x0000555555555176 <+81>:    mov    %eax,0x2eb4(%rip)        
# 0x555555558030 <b>

We can directly translate it to bare assembly code we used in the


previous chapter and put corresponding pseudo-code in comments:

movl   $1, a              # 1 -> (a)


movl   $1, b              # 1 -> (b)
mov    b, %edx            # (b) + (a) -> (b)
mov    a, %eax
add    %edx, %eax
mov    %eax, b
mov    a, %eax            # (a) + 1 -> (a)
add    $1, %eax
mov    %eax, a
mov    b, %edx            # (b) * (a) -> (b)
mov    a, %eax
imul   %edx, %eax
mov    %eax, b

24
Chapter 2 Code Optimization

Now we can exit GDB:

(gdb) q
A debugging session is active.

        Inferior 1 [process 2249] will be killed.

Quit anyway? (y or n) y
coredump@DESKTOP-IS6V2L0:~/pflddr/x64/Chapter2$

GDB Disassembly Output – Optimization


If we compile and link the program in optimization mode:

coredump@DESKTOP-IS6V2L0:~/pflddr/x64/Chapter2$ gcc
ArithmeticProjectC.cpp -O1 -o ArithmeticProjectC

and after repeating the same steps in GDB, we get the following output:

(gdb) disass main


Dump of assembler code for function main:
=> 0x0000555555555125 <+0>:     movl   $0x2,0x2f01(%rip)        
# 0x555555558030 <a>
   0x000055555555512f <+10>:    movl   $0x4,0x2ef3(%rip)        
# 0x55555555802c <b>
   0x0000555555555139 <+20>:    mov    $0x0,%eax
   0x000055555555513e <+25>:    retq
End of assembler dump.

This corresponds to the following pseudo-code:

mov $2, a   # 2 -> (a)


mov $4, b   # 4 -> (b)

Please note that the compiler also chose to put memory cell “b” first
(000055555555802c) and then memory cell “a” (0000555555558030).

25
Chapter 2 Code Optimization

What happened to all our assembly code in this executable? This code
seems to be directly placing the end result into the “b” memory cell if we
observe. Why is this happening? The answer lies in compiler optimization.
When the code is compiled in optimization mode, the compiler can
calculate the final result from the simple C/C++ source code itself and
generate only the necessary code to update corresponding memory
locations.

Summary
In this chapter, we looked at assembly language code produced by a
debugger via disassembling binary code. Then, we reversed it to C and C++
code. We also compared the disassembly output of nonoptimized code to
optimized code and understood why.
The next chapter refreshes number representations, especially the
hexadecimal one.

26
CHAPTER 3

Number
Representations
Numbers and Their Representations
Imagine a herder in ancient times trying to count his sheep. He has a
certain number of stones (twelve):

However, he can only count up to three and arranges the total into
groups of three:

© Dmitry Vostokov 2023 27


D. Vostokov, Foundations of Linux Debugging, Disassembling, and Reversing,
https://doi.org/10.1007/978-1-4842-9153-5_3
Chapter 3 Number Representations

The last picture is a representation (a kind of notation) of the number


of stones. We have one group of three groups of three stones plus a
separate group of three stones. If he could count up to ten, we would see a
different representation of the same number of stones. We would have one
group of ten stones and another group of two stones.

Decimal Representation (Base Ten)


Let’s now see how twelve stones are represented in arithmetic notation if
we can count up to ten. We have one group of ten numbers plus two:

12dec = 1 * 10 + 2 or 1 * 101 + 2 * 100

Here is another exercise with 123 stones. We have 1 group of ten by


ten stones, another group of 2 groups of ten stones, and the last group
of 3 stones:

123dec = 1 * 10*10 + 2 * 10 + 3 or 1 * 102 + 2 * 101 + 3 * 100

We can formalize it in the following summation notation:

Ndec = an*10n + an-1*10n-1 + … + a2*102 + a1*101 + a0*100


0 <= ai <= 9
Using the summation symbol, we have this formula:

n
Ndec = ∑ ai*10i
i=0

28
Chapter 3 Number Representations

Ternary Representation (Base Three)


Now we come back to our herder’s example of twelve stones. We have 1
group of three by three stones, 1 group of three stones, and an empty (0)
group (which is not empty if we have one stone only or have thirteen
stones instead of twelve). We can write down the number of groups
sequentially: 110. Therefore, 110 is a ternary representation (notation) of
twelve stones, and it is equivalent to 12 written in decimal notation:

12dec = 1*32 + 1*31 + 0*30

Ndec = an*3n + an-1*3n-1 + … + a2*32 + a1*31 + a0*30


ai = 0 or 1 or 2

n
Ndec = ∑ ai*3i
i=0

Binary Representation (Base Two)


In the case of counting up to two, we have more groups for twelve stones:
1100. Therefore, 1100 is a binary representation (notation) for 12 in
decimal notation:

12dec = 1*23 + 1*22 + 0*21 + 0*20

123dec = 1*26 + 1*25 + 1*24 + 1*23 + 0*22 + 1*21 + 1*20 or


11110112

Ndec = an*2n + an-1*2n-1 + … + a2*22 + a1*21 + a0*20


ai = 0 or 1

n
Ndec = ∑ ai*2i
i=0

29
Chapter 3 Number Representations

Hexadecimal Representation (Base Sixteen)


If we can count up to sixteen, twelve stones fit in one group, but we
need more symbols: A, B, C, D, E, and F for ten, eleven, twelve, thirteen,
fourteen, and fifteen, respectively:
12dec = C in hexadecimal representation (notation)

123dec = 7Bhex

123dec = 7*161 + 11*160

n
Ndec = ∑ ai*16i
i=0

Why Are Hexadecimals Used?


Consider this number written in binary notation: 1100010100112. Its
equivalent in decimal notation is 3155:

3155dec = 1*211 + 1*210 + 0*29 + 0*28 + 0*27 + 1*26 + 0*25


+ 1*24 + 0*23 + 0*22 + 1*21 + 1*20

Now we divide the binary number digits into groups of four and write
them down in decimal and hexadecimal notation:

110001010011

12dec 5dec 3dec

Chex 5hex 3hex

We see that hexadecimal notation is more compact because every


four binary digit group number corresponds to one hexadecimal number.
Table 3-1 lists hexadecimal equivalents for every four binary digit
combination.

30
Chapter 3 Number Representations

Table 3-1. Hexadecimal Equivalents for Every Four


Binary Digit Combination
Binary Decimal Hexadecimal

0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F

In GDB and other debuggers, memory addresses are displayed in


hexadecimal notation.

31
Chapter 3 Number Representations

Summary
This chapter refreshed different representations of a number, including
hexadecimal notation.
The next chapter introduces pointers. We rewrite our arithmetic
program from Chapter 1 using pointers to memory and use the GDB
debugger to execute instructions one by one and watch changes
to memory.

32
Random documents with unrelated
content Scribd suggests to you:
Olon outous teki heidät kaikki ylen harvapuheisiksi. He nauttivat
kukin erikseen, katsomatta edes toisiinsa.

"Maassa on kastetta", sanoi Lenzy vihdoin.

Ja hän ojensi jalkansa pehmeään ja tuoksuvaan heinikkoon. Ne


näyttivät melkein sinertävän valkoisilta. Lenzy ja Mirka eivät
milloinkaan päivettyneet, eivät edes paahtavimmassa paisteessa.
Heidän ohimoissaankin risteili kalpeita, sinisiä suonia.

Lenzy käyristi varpaansa ja taittoi suuren sinikellon, joka jäi


varpaitten väliin.

Hän oli hyvä, viisas ja rauhallinen eikä koskaan unohtanut, että oli
sisartaan ja Katinkaa vuotta vanhempi.

Mutta Mirka ajatteli yhä käärmeitä.

"Kun käärme poikii", selitti hän äkkiä, "niin se kiipee puuhun, ja


pudottaa sieltä poikansa".

"Lorua", sanoi Lenzy, "käärmeet munivat munia. Aurinko hautoo


ne."

Katinka ei kuullut kumpaakaan.

"Me tullaan tänne", hän puheli. "Me ollaan jo isoja,


koulunkäyneitä, — kukaan ei voi enää kieltää. Me maataan täällä
koko yö."

Tuntui selvään hunajainen lemu, keltamataran tuoksu. Puitten


välitse näkyi vilahdus kreikkalaistemppelistä. Se oli valkea kuin
rukous.
"Tytöt!" sanoi Katinka yht'äkkiä. "Luvatkaa minulle, mutta pyhästi,
että tulemme kaikki kolme Soldat-niitylle vainajina. Sanokaa näin:
missä ikinä lepäänkin viimeistä untani, valtameren pohjassa tai
Siperian tundrilla tai — tai Saharan hiekassa tai missä muualla
valjenneet luuni lienevät, — niin tahdon tulla Soldat-niitylle
vainajana."

"Valjenneet luuni", hän lausui erityisellä juhlallisella kaameudella;


hän oli sen sanan edellisenä päivänä lukenut jostain
intianikertomuksesta.

He tarttuivat toisiaan käsistä, kuumin sormin. Ja kaikki kolme


lausuivat yht'aikaa valansa:

"Missä ikinä lepäänkin viimeistä untani… niin tahdon tulla


Soldat-niitylle vainajana."

Kaikki kolme jäivät tuijottamaan valkoisiin, irrallisiin usviin, jotka


pitkinä liepeinä liikkuivat yli yöllisen niityn, ikäänkuin autuaitten
varjot.

Kuu nousi kaisloista ja vedestä, vaskenpunaisena kuin tuntematon


jumaluus. Ihmeellinen, pelokas tunne valtasi heidät, salaperäinen
vavistus tuon tuntemattoman tulipallon edessä. He olivat kuin yksin
maailmassa, hitaasti nouseva kuu, ja he kolme paljasjalkaista,
vuoteistaan karannutta tyttölasta. He olisivat halunneet polvistua,
itkeä nyyhkyttää ja rukoilla kuuta…

Sitten Katinka sanoi:

"Nyt mennään Mustaanjokeen uimaan."


Ei kukaan pannut vastaan. Tänä yönä oli kaikki sallittua ja
mahdollista. Tuntui vain päätähuimaavalta, pyörryttävältä. Mennä
Mustaanjokeen uimaan ja keskellä yötä! Seuraavaa aamua ja päivää
ei ollut olemassakaan.

He olivat jo tuiki syntisiä, ilmankin!

He kiersivät Kuninkaan ohi joelle. Koirankopissa haukahtivat


jäniskoirat, Ilo ja Piili. Tarhassa märehtivät torkkuvat lehmät. He
kantoivat kukin sukkiaan ja kenkiään.

Joen rannalla tuoksui kuten Soldat-niitylläkin, mutta senlisäksi


tuoksui vesi ja raskaat, kultaiset ulpukat. Joki tuli Mustastakorvesta;
sen lähteet olivat siellä, missä Elämänlähdekin.

Kuu yhä nousi ja hopeoitui, pienentyen samalla luonnolliseen


kokoonsa.
Se oli jo korkeimman lepän latvassa.

Lenzy koetteli jalallaan vettä.

"Tytöt", hän kuiskasi. "Luuletteko, että hän hukkui tähän?"

"Kuka hukkui?" kysyi Mirka, koettaen asettautua kuun säteeseen.

"Hän, — vanhan herran pikku piikatyttö, — joka rikkoi maljakon."

Mutta Katinka kietoi palmikoitaan päälaelle eikä sanonut mitään.


Hän vain ajatteli, mlnkätähden Lenzy mahtoi sanoa "vanha herra",
vaikka se oli hänen äitinsä-äidin isä.

Hetken päästä he jo tanssivat piirissä keskellä jokea, toisiaan


kädestä pidellen, keskellä kuutamoa.
12.

Ylinnä Hovissa oli Mummuli, siitä ei ollut epäilystä. Katinkalle se oli


päivänselvää. Niinkuin Mummuli päivällispöydässä istui ylinnä, niin
hän Katinkan tajunnassakin istui jollain näkymättömällä
valtaistuimella. Hän oli sen arvojärjestyksen huippu, joka yhä aleten
jatkui Katinkaan, Lenzyyn ja Mirkaan saakka, ja johon kuului
Grosspapa, äiti, isä, sedät, tädit, serkut ja pikkuserkut ja
satunnaisina vieraina kaikki Rabet Lontoosta, Parisista, Pietarista ja
aina Madeirasta asti. Tämä oli maailma sinänsä, ja siihen kuului vielä
naapurihovien asukkaat, kaikki Mendtit, Riemenschneiderit, Ripasit ja
Adaridit. Paitsi sitä oli Hovissa tosin toinenkin maailma, mutta sekin
oli maailma sinänsä eikä kuulunut tähän. Se avautui keittiön puolella,
väentuvassa, pajassa ja Ahokkaan kylässä.

Katinka tiesi hyvin kuuluvansa Hovin ylämaailmaan. Mutta se ei


estänyt häntä tuntemasta alituista, herkeämätöntä vetoa tuota
toista, alamaailmaa kohtaan. Lenzy ja Mirka eivät sinne koskaan
pyrkineet, heille riitti ylämaailma. Mutta Katinka ei saanut rauhaa,
hänen oli oltava joka paikassa!

Alamaailmaan kuului koko keittiön asujamisto, Sokia-Mari, Kyökki-


Ieva, Sisä-Miina, Pyykki-Miina, pikku-Tilta, Hamusen-Ieva, Anni ja
Masha, venakko, sitten vielä Kuski-Heikki, Suhonen, puutarhuri, jolla
oli oma tupansa puutarhan kupeella, ja Suhoska, hänen vaimonsa,
jolla oli kylmänvihat jaloissa. Nämä olivat läheisimmät, mutta lisäksi
oli vielä epälukuinen määrä lampuodin piikoja ja renkejä; karjakkoja,
Tupa-Anni lapsineen, seppä ja Ahokkaan väki.

Kuninkaan, lampuodin, laita oli mutkallisempi. Ei ollut hyvä sanoa,


mihinkä hän näistä kahdesta maailmasta oikein kuului. Katinka ei
milloinkaan nähnyt hänen käyvän pääovesta, ja se oli sentään
Katinkan silmissä muuan varmimpia tuntomerkkejä ylämaailmaan
kuulumisesta. Mutta Kuningas ei myöskään tullut keittiön tietä, kuten
muu alamaailman väki, hän meni kylkirakennuksen sivuovesta
suoraan Grosspapan huoneeseen. Hän oli kuin taivaanvuohi näitten
kahden maailman välillä, käski toista ja totteli toista.

Toinen maailma alkoi jo keittiön portaista, takapihasta, jolla oli


kuin oma kasvitarhansa, takapihan villi yrttitarha, hyöstynyt
ruoanjätteistä ja likavesistä. Hirvittävän korkeita, vihaisia nokkosia,
jotka polttivat kädet palorakoille, takiaisia, jotka keräsivät pölyn
leveille lehdilleen, löyhkääviä koiruohoja, joita Anni keräsi ja kuivatti
kimpuiksi, ja kukkivia hullukaaleja, joilla oli myrkyllinen, likaisen
kirjava kukanterä.

Hiukan kauempana aidan takana oli kanojen ja kukkojen


teloituspaikka, — siellä ne lensivät ilman päätä, kaula surkeasti
verissä.

Jääkellarissa pidettiin talvea vangittuna kolmen oven ja kolmen


lukon takana.

Viiniholvissa sensijaan oli Sokia-Marin komero. Hän asui siellä jo


toista vuosikymmentä, keskellä tynnyreitä ja viinipulloja, joita
Leopold Raben lontoolaiset veljenpojat joka vuosi lähettivät
viiniviljelyksiltään päiväntasaajan seuduilta. Hän elosteli siellä kuten
hiiret tai tuhatjalkaiset, jotka juoksentelivat pitkin kiviseiniä.

Kukaan ei tarkalleen tiennyt hänen ikäänsä, ei edes hän itsekään,


mutta hän oli varmasti vanhempi Grosspapata ja Hamusen-Ievaa ja
itse lampuodin isää, vanhaa Kuningastakin. Hän oli vanhin olento
koko Hovissa, vanhempi itse Hoviakin, jonka päärakennus oli ollut
vasta salvoksella, kun Mari tuli taloon Mummulin imettäjäksi. Hän oli
vielä vanhan herran peruja, kuten Fataburin lasinpuhaltimien jätteet
ja salatieteelliset kirjat ullakolla tai hänen selloviulunsa
metallikirjaimineen vierashuoneessa.

Hänen oli tapana istua viinikellarin kynnyksellä, silmät


rävähtämättä päin aurinkoa, päässä iänikuinen, vanhuuttaan
vihertävä tanu, kova ja kiiltävä kuin kuoriaisen koppa. Silmiä kattoi
valkea, linnun luomen kaltainen kaihi; vaatteista uhosi merkillinen,
tunkkainen ja kostea haju.

Hän näytti aina ikäänkuin jotain kuuntelevan. Ajanvietteekseen


hän leikkeli räsymattoja varten tilkkuja ja keri ne suuriksi, kirjaviksi
kiekoiksi. Mutta sitä tehdessään hän alati kuunteli. Hän väitti
kuulevansa Mustankorven kohun. Toiset nauroivat ja sanoivat hänen
puhuvan päättömiä, mutta Sokia-Mari pysyi itsepintaisesti
väitteessään. Hän kuuli sen varmasti, yöllä tosin selvemmin kuin
päivällä. Se oli ikäänkuin tasaisesti virtaava, huokaava ääni, joka oli
kaikkien muitten moninaisten äänien alla.

Hän muisti vielä ajat, jolloin korpi alkoi heti aidan takaa, ja susi
uskalsi talvisin pihamaalle. Pellot, vainiot, puutarhat, kaikki on
vähäistä korven rinnalla. Vanhan herran vaunutiestäkin on jäljellä
vain viheliäinen polku. Kaikki, mitä ihmiskäsi ja järki ovat
aikaansaaneet, on kuin nuo kirjavat räsymaton kaistaleet.

Katinka pujahti keittiöön, milloin vain taisi. Itse ilmakin siellä oli
erikoisen mieluinen ja hivelevä, täynnä höyryjä ja käryjä, juuston,
vastasiivilöidyn, vielä vaahtoavan maidon ja nousevan taikinan
tuoksua. Aina oli siellä touhua, räiskettä, kilinää-kalinaa!
Katinka rakasti katsella Kyökki-Ievan lihavilla, tanakoilla
käsivarsillaan, joissa oli tiheää, untuvaista ihokarvaa, sotkevan
taikinaa, vierittävän siitä koukistettujen hyppysiensä alla
uskomattoman nopeasti sämpylöitä, jotka sitten uunissa paistuivat
kauniin vaaleanruskeiksi, tai sitten käsittelevän patoja ja liesirenkaita
paljain sormin, jotka näköjään olivat tuiki tunteettomat kuumuudelle.

Katinka rakasti väen hapanta katajakaljaa, jota jokainen joi


suoraan puukiposta, ja suolaisia särkiä, joita ei koskaan näkynyt
muualla kuin väen pöydässä. Niillä oli ihmeellisen suloinen, kielletty
maku. Niitä täytyi vain nauttia varkain. Ja oli kuitenkin miekkoisia,
jotka saivat niitä joka ateriaksi!

Keittiön takana oli piikojen makuukomerot, kaksi matalaa, kaari-


ikkunaista huonetta vasemmassa kylkirakennuksessa. Niissä oli aina
tuulettamaton, umpinainen haju. Mutta muuten ne olivat peräti
viehättävät nekin, kuten keittiökin. Huiskin, haiskin kampojen ja
eriväristen hiustukkojen seurassa siellä oli rasvaisia ja savuttuneita
kirjoja, joilla oli uteliaisuutta kiihoittavat nimet, kuten Uusi
Kenoveeva eli Roosa Tannenpurista ja muuan aivan nokinen ja
yltäyleensä ruskea Holperin Äijä, joka oli kuin paistinpannussa
käynyt; sitäpaitsi Satakieli eli Sata laulua Suomen kansalle ja Suuri
Egyptiläinen Unikirja, jota Kyökki-Ieva erityisesti tutkisteli.

He näkivät alati unia öisin. Ja he puhuivat unistaan, ikäänkuin


jostain täysin todellisesta, ne herättivät heissä aivan samanlaista
pelkoa tai iloa. Katinka kuunteli korvat pystyssä, kun Kyökki-Ieva
pani kädet ristiin vatsalleen ja sanoi: "Pankaas nyt merkill', kyll' se
nyt kuoloo." Kyökki-Ievan unet merkitsivät aina kuolemaa ja
tapaturmia. Hän näki leipovansa rinkelejä, täpötäynnä suuria, mustia
rusinoita, taikka oli keittävinään soppaa, mustaa kuin piki, kaikki
perin pahoja enteitä. Kaikki oli täynnä merkkejä; sakset putoilivat
kärki edellä; lukki oli yöllä kutonut seittinsä uunin suuhun. Yksinpä
hänen liikavarpaansakin ennustelivat; niitten avulla hän tiesi sateen
ja rajuilman tulon.

Oli ihmeellistä; kaikki nämä Ievat, Annit, Sisä- ja Pyykki-Miinat,


Heikit, olivat omassa maailmassaan tuiki toisenlaisia kuin
joutuessaan Grosspapan ja Mummulin maailmaan. Ylämaailmassa he
olivat vähäpuheisia, hiljaa astelevia, vastasivat vain kysyttäessä.
Mutta niin pian kuin keittiön ovi oli sulkeutunut heidän takanaan, he
olivatkin tuota pikaa isoäänisiä, lörppöjä, kujeilijoita, aika äkämyksiä,
mutta aina kadehdittavan hullunkurisia. Saattoi melkein unohtaa
heidän olevan aikaihmisiä. Heille sai nauraa katketakseen.
Illallisastiat pestyään he saattoivat iloitella tuntikausia, niinkuin ei
seuraavaa aamua olisi ollut olemassakaan, pistää keskellä keittiön
lattiaa tanssiksikin, jos vain Sepän-Anton tai joku muu Ahokkaan
pojista ilmestyi keittiöön, — laulella päättömiä lauluja, kinastella,
loruta ja nauraa loppumattomiin.

Anni lauloi muuatta muka puolalaista laulua, jossa aina toistui:


luppa-tsuu, luppa-tsuu. Mutta kun häneltä ruvettiin kyselemään,
mistä hän sen oli oppinut, herkesi hän siihen paikkaan. Olipa ollut
muuan tensikka, venäläisen upseerin tensikka, joka oli opettanut.
Hän sanoi sen melkein vihaisesti eikä enää laulanut. Kaunis Sisä-
Miina sadatteli aina Mummulia lyhyistä vaatteista, joita jokaisen
Hovin palvelustytön täytyi sitoutua käyttämään pestin ottaessaan.
Mutta toden teolla ei mikään puku olisi paremmin sopinut hänen
kamarineitsytkauneudellaan kuin juuri valkeat kohohihat, punainen
hame, ruohonpäiset liivit ja kirjava huivi, jonka hän solmi harteilleen
peilin edessä, mikä ei ollut kananmunaa suurestikaan isompi.
Hän ryöpsähti keittiöön, heitti tarjottimen pöydälle ja tarttuen
vantteraan ja raskaskääntöiseen Kuski-Heikkiin, alkoi huudella:

"Kaheksa komiaa tyttöö Hoviss' ja Heikk' yheksäs!"

Kaikki tiesivät, että Heikki vaihtelevalla onnella kosiskeli Sisä-


Miinaa, ja että Miina kiemaili hänelle, mutta yht'aikaa myös nuorelle
piispansaarelaiselle perämiehen alulle.

Katinka ei tainnut kyllin ihastella näitten alamaailman ihmisten


elämää. Se näytti olevan pelkkää ilonpitoa. He saivat suolaisia särkiä
ja hapankaljaa niinpaljon kuin halusivat. Heitä ei pidetty laihalla
ruoalla, että tulisivat keskeltä katkeaviksi kuin vaapsiaiset!

Katinkalle jäi muistiin muuan ilta. Hän, Katinka, makasi jo


ristikkovuoteessaan ja rallatti ratokseen; ikkunat puutarhaan olivat
auki, oli tuollainen lämmin kesäilta, vain kuin kuuman päivän jatko.
Yht'äkkiä tulee siihen ties mistä, Anni, ja hetken päästä Sisä-Miina;
Katinka yhä rallattaa, nyt jo kovemmin. Anni ja Sisä-Miina alkavat
pyörähdellä, Katinkan rallatuksen mukaan, ja samassa on siinä
pikku-Tiltakin, hänkin pyörähtelee, mutta yksinään. Katinkalla on
sanomattoman hauskaa, hän ihan rakastaa noita, jotka tuossa
lattialla pyörähtelevät, ja hänestä tuntuu, että hekin rakastavat
häntä. Tätä menoa voisi jatkua vaikka koko yö, aivan kuin
surviaisten tanssia tuolla ulkona kesäisessä ilmassa!

Seuraavana päivänä tuli vieraita Vongurista, Vongurin vanha


salaneuvoksetar, joka aina puhui miesvainajastaan, Herrassa
nukkuneesta Abram Abramovitshista, kuollut neljännesvuosisata
takaperin, ja paitsi sitä Pesusta koko Ripasin joukkue, rouva
ruiskukanvärinen silkkihame yllä, ja herra, mansetinnappeina
kultakimpaleet omista siperialaisista kultakaivoksista.
Illempana Mummuli istutti vieraansa takaparvekkeelle:
piikatyttöjen oli näytettävä vieraille tanhujaan ja piirihyppyjään
ruohikolla. Tällaiset näytelmät miellyttivät Mummulia, ne hyväilivät
hänen valtiatarvaistojaan, aivankuin hän elonkorjuutalkoitten jälkeen
tapasi pylväsportailla istuen ottaa vastaan ohikulkevan talkooväen
kumarrukset ja niiaukset.

Katinka, suittuna, tärkkihameet yllä, valkoisissa kenkiin saakka,


katseli tätä menoa toisten takaa. Hän ei ollut uskoa silmiään.
Olivatko nämä todella samoja, jotka eilen hänen rallattaessaan olivat
tanhunneet kuin hyttyset? Nämäkö kankealiikkeiset, saamattomat ja
hiestyvät olennot, jotka tuossa pakoitetusti pyörähtelivät?

Mutta vieraat taputtivat kohteliaasti käsiään, Pesun Ripas


ääneensä nauraa höristen ja huutaen "da capo", johon hänen
poikansa täydestä kurkusta yhtyivät. Vongurin salaneuvoksetar tyytyi
katsomaan näytelmää lornjetillään. Mummuli antoi armollisesti
merkin, ja väki sai keittiössä vehnäskahvit.

Katinkalle vain jäi kummallinen, kaiveleva tunne, melkein kuin


häpeää.

13.

Katinka eroitteli mielessään kaiken elottoman ja elollisen Hovissa


hyviin ja pahoihin. Edelliset olivat hyvänsuopia ja rakastettavia, niitä
olisi halunnut hyväillä ja halata, likistäytyä lähekkäin, nimittää
rakkailla, suloisilla nimillä, ottaa vuoteeseensa ja nukkua niitten
keralla. Nämä hyvänsuovat esineet ja olennot olivat useimmiten
hiljaisia ja vaiteliaita, ne olivat kukkia, tai Tilkoaniemen notkon
valkeita, punasilmäisiä hiiriä, tai sitten huonekaluja, kuten etehisen
iso kaappikello. Perin harvoin ne olivat ihmisiä.

Hyviä oli vain harvassa; pahansuopia ja peljättäviä verrattoman


paljon enemmän. Ja niitä oli kohdeltava aivan eri tavalla. Niitä täytyi
kiertää kaukaa tai sitten uhikseen ärsytellä ja härnätä ja senjälkeen
suinpäin paeta, kun ne kävivät vaarallisiksi.

Niitä oli todella suuri joukko: Mustankorven sudet, Hovin yläkerta


ja isot kuvastimet alasalissa, ukkosilma, mustalaiset ja Vanha-
Kuningas.

Hyvänsuovista esineistä ja olennoista ei usein tiennyt enempää


kuin hyvänolon tunteen, mikä niistä kuin salaa uhosi. Ne eivät
koskaan hyökänneet eivätkä ajaneet takaa. Ne vain odottivat, että
menisi ohi ja huomaisi heidät. Herahti joskus vastustamaton
hyvänolon tunne koko ruumiiseen ja sieluun, niin että varmasti tunsi
jonkun tuntemattoman kukan tuoksuvan tiepuolessa tai turpean,
viheriä juovaisen kurpitsan verannan seinämällä ystävällisesti
ajatelleen. Niillä ei useinkaan ollut muuta puhetta kuin tuoksu; se oli
niitten ainoa kieli.

Katinka toi kukkia vuoteeseensa, hän nukkui niitten keralla.


Etehisen kaappikello taas oli tosin liian iso mahtuakseen Katinkan
ristikkovuoteeseen, mutta sensijaan oli Katinka kerran — jo kauan
sitten — viettänyt yönsä siinä.

Se oli tapahtunut näin. Katinka ja kaappikello olivat ystävykset jo


ammoisista ajoista. Se oli perin merkillinen kello. Sen taulussa, joka
oli iso ja pyöreä, vaihtelivat aina vuorokauden ajan mukaan eri
kuvat, jotka Katinkalle käsittämättömällä tavalla ilmestyivät sen
sisimmästä. Muutos tapahtui hyvin hitaasti, milloinkaan ei voinut
minuutilleen sanoa, milloin toinen tuli ja toinen meni. Mutta koko
kello muutti muotoa kuvien keralla, ikäänkuin suuret kasvot, jotka
vaihtoivat ilmettä; se oli iloinen ja hilpeä, kauhistava ja salaperäinen,
naurava ja itkevä, aina sen mukaan kuin kuvatkin. Aamulla oli
näkyvissä verevä ja pulloposkinen aurinko, jonka hyvätuulinen hymy
tarttui koko kellotauluun, numerot, viisarit, kaikki nauroivat, ja
aurinko oli kuin syksyinen omena. Mutta keskipäivällä olivat kellon
kasvot tyynet ja miettivät; näkyvissä oli hiljainen maisema, pieni
talo, jonka takana kasvoi puita, ja keltainen vainio, täynnä
keskipäivän uneliasta lepoa. Illalla purjehti näkyviin laiva, täydessä
lastissa, purjeet täynnä tuulta, matkalla tuntemattomille merille. Se
jätti jälkeensä riuduttavan ikävän, kuin vaahtovanan, alkaessaan taas
liukua kellon syvyyksiin.

Mutta mitä oli yöllä? Minkälaiset olivat kellon kasvot, silloin koko
Hovi nukkui, Grosspapasta ja Mummulista alkaen Lenzyyn ja Mirkaan
ja aina Sokiaan-Mariin asti alhaalla kellariholvissaan. Ah, Katinka
parka ei saisi sitä koskaan tietää, hän nukkui aina silloin jo sikeässä
unessa, kun kello ilmaisi viimeiset salansa yölle ja pimeydelle.

Mutta eräänä yönä Katinka hiipi paitasillaan etehiseen,


puristettuaan ruoholaukkaa silmiinsä hereillä pysyäkseen. Hän
kohotti kynttilänsä, ja kello tuijotti häneen synkkänä ja uhkaavana;
sen taulussa oli luinen käsivarsi, joka käänsi kumoon tuntilasia, ja
viisarit näyttivät kahtatoista. Katinka ymmärsi: se oli kuolema.

Samalla narahti keittiön ovi, ja puolikuolleena säikähdyksestä


Katinka pujahti kellokaappiin. Joku kulki ohitse, luultavasti Sisä-
Miina, Katinkan kyyhöttäessä ahtaassa kaapissa. Sen jälkeen hiljeni
kaikki, hän oli kuulevinaan vain suuren ja ystävällisen sydämen
sykinnän. Hän oli keskellä salaperäistä koneistoa, joka mittasi aikaa.
Kaikki salaisuudet olivat lähellä, käden ulottuvilla; täältä jostain,
hänen päänsä yläpuolelta, lähtivät liikkeelle kaikki nuo salaperäiset
kuvat. Yhä raukeammaksi, yhä uneliaammaksi hän kävi, yhä
turvallisemmaksi hänen olonsa, kunnes hän vihdoin nukkui kellon
suojaan, niinkuin olisi nukkunut maailman sydämelle.

Tällaisia olivat hyvänsuovat. Mutta yhtä ankara oli ahdistus, mikä


lähti pahansuovista olioista.

He ovat vielä hyvin pieniä, aivan selässä kannettavia, ainakin


Katinka ja Mirka. He tekevät pitemmät retkensä aina hoitajiensa
selässä, Katinka Annin, Mirka Mashan, Agnes-tädin venakon, Lenzy
saa juosta kipittää omin jaloin, minkä pääsee.

He ovat lähteneet marjaan, kiivenneet yli aidan ja uponneet


ihanaan, vihreään ruohoon. "Kasso pomppoi", sanoo Anni ja poimii
mansikoita. "Miljoonapomppoja!" kirkaisee Katinka. Mutta samassa
tuokiossa kasvaa heidän eteensä äkkiä kuin maasta nokinen, tuima,
ärjyvä hirviö, nahkavyöliina edessä ja kädessä moukari.

"Pois siint' heinää tallaamast'! Vai työ täss' miu marjojai.


Pääsettekös, taikk'."

Mirka pudottaa ropeensa ja alkaa kirkua, Mashan yrittäessä yli


aidan. Anni aikoo juuri aukaista suunsa syytääkseen aikamoisen
sanaryöpyn murjaanille päin naamaa. Mutta sitä ennen tapahtuu
jotain.

Katinka seisahtuu äkämystyneen hirviön eteen, jonka polviin hän


vaivoin ylettyy, ja sanoo:
"Ei ne ole seppäsedän mansikoita, ne on Jumalan mansikoita!"

Ja nyt saavat kaikki nähdä: hirviön käsi hervahtaa, noen ja tahman


keskeltä avautuu leveä suu, täynnä mahtavia, valkoisia hampaita, ja
samassa pärähtää tärisyttävä nauru:

"Kuulkaa noit' tyttölöi… Vai Jumalan marjoi… No poimikaa sitt'


Herran nimmee…"

Susia pelkäsi Katinka siitä saakka, kun ne talvella raatelivat jäällä


Dianan.

Diana oli silloin tosin hylkykoira, lahjoitettu pari vuotta sitten


vanhuuttaan muutamalle Hovin torpparille. Mutta Katinka rakasti sitä
kuitenkin, nykyisessä alennustilassakin, kun se nälkäisenä ja
takkuisena, häntä koipien välissä, kaukaa kiersi Hovia. Se oli yhtenä
ainoana talvena uskomattomasti raaistunut; siitä oli tullut oikea
kulkuri, luihuileva, salavihainen ja arka; sen luonne oli muuttunut
ulkoasun keralla. Sen kyljet olivat täynnä vereksiä puremia, sillä se
oli aina sotajalalla muitten koirien kanssa; se ontui toista
etujalkaansa. Se ei kuulunut enää mihinkään koirayhteiskuntaan, ei
entiseen yläluokkaansa eikä nykyisen alemmuutensa tovereihin,
kyläkoiriin; molemmat kohtelivat sitä yhtä suurella epäluulolla ja
vainolla.

Hoviin se kuitenkin tunsi epäämätöntä vetoa, se kaarsi sitä, milloin


suinkin toisten koirien, entisten metsästystoveriensa ärhentelyltä
taisi, surullisesti ja ikävöivästi vinkuen. Se nuuski heti kesän alussa
selville, että sen entiset omistajat olivat palanneet, metsästystorven
tuttu raiku saattoi sen iloiseen raivoon, se aikoi suoraa päätä syöksyä
entisen onnensa sijoille. Mutta paratiisi oli suljettu, ja Kyökki-Ieva
ajoi sen luudaniskuilla loitommalle. Tämän jälkeen se ei uskaltanut
tulla jääkellaria kauemmaksi. Lampuodin, Kuninkaan, lapset
heittelivät sitä kivillä, sille oli kielletty antamasta ruokaa.

Katinka ei alistunut kieltoon, hän päinvastoin keräsi luita ja


leivänkannikoita ja syötti niitä Dianalle aidan takana, milloin Kyökki-
Ievan silmä vältti. Oi, Diana, Diana! He itkivät molemmat, Katinka ja
Diana, — koira uskaltamatta nuolla kiitokseksi lapsen ruskeaa kättä,
pää kallellaan, veden valuessa kellanvihreistä silmistä; herra ties,
miten veristä vääryyttä se tunsikaan kärsineensä!

Mutta eräänä kesänä ei Dianaa enää näkynyt missään. Nuori


Kuningas kertoi Katinkalle tavanneensa kerran talvella vereksiä
suden jälkiä jäältä Kataja- ja Koprasaaren väliltä sekä karvatukkoja,
jotka kaikesta päättäen olivat Dianan. Diana oli siis päässyt
autuaammille metsästysmaille.

Sinä yönä Katinka ei saanut unta ristikkovuoteessaan, vaikka olisi


lukenut Herran siunauksen kaikilla eri kielillä, mitä Hovissa puhuttiin.

Hän oli kuulevinaan susien ulvonnan, kun ne painuivat


Mustastakorvesta saarien välitse jäälle ja odottivat Dianaa,
veripunainen kita ammollaan kohti kylmää ja terävää kuuta.
Hovissakaan eivät aina kukkineet jasmiinit, täälläkin oli hankia ja
pakkasia!

Katinka vaipui vähitellen eräänlaiseen horrokseen. Hän oli


olevinaan Diana. Mutta ei äskeinen kapinen, raihnainen Diana, vaan
nuori, sileäpintainen ja voimakas. Hän on iltayöstä maannut jossain
lämpimässä ja ahtaassa kopissa, heiniin hautaantuneena, jotka
mieluisasti syyhyttivät sieraimia. Mutta vastustamaton veto vie hänet
talviyöhön ja jäälle. Hän haukahtaa kuulle kuin vanhalle tutulle, hän
päästää ulvonnan lampuodin ikkunan alla, josta vastaa vain
halpaantuneen Vanhan-Kuninkaan ähkinä. Sensijaan ei kuulu nuorta
Kuningasta eikä hänen tuliluikkuaan. Ja Diana kiertää kerran koko
Hovin ja syöksähtää sitten pitkin koivukujaa alas jäälle läpi jäätyneen
pajupensaikon.

Kuinka lumi kimaltaa, kuinka käpälät miltei jälkiä tekemättä


hipovat hankea! Jäällä on heikkoa, himmeää valoa, Koprasaaren
kuusiryteikkö on musta ja liikkumaton. Ihanaa on näin juosta ja
tuntea oman voimansa hively!

Yht'äkkiä täyttää outo ja ärsyttävä haju ilman… Katajasaaren


takaa häilähtelee kuin harmaita pisteitä, ikäänkuin rantakivet olisivat
alkaneet elää. Kuuluu haukku, — melkein kuin koiran, vain hieman
venytetympi — uu — uu…

Pako on myöhäistä. Harmaat kivet muuttuvat susiksi, ne


hyökkäävät hänen päälleen. Niitä on monta, kolme, neljä… hän
näkee, kuinka niitten kuuma huounta muuttuu huuruksi pakkasessa.
Ne irvistävät aivankuin koirat, niin että käyrät, terävät
kulmahampaat näkyvät. Ja Dianan torjuessa kolmea, puree neljäs
häntä niskaan…

"Sudet, — sudet!…"

Katinka heräsi omaan huutoonsa, katseli hetken aikaa tyhjin,


kauhistunein silmin ympärilleen ja vetäisi sitten peitteen yltäylitseen.
Sen alla on pimeä ja lämmin, on kuin etana kuoressaan. Mutta
parasta lie sentään rukoilla.. Kun vain tietäisi, mitä kieltä Jumala
parhaiten ymmärtää… "Müde bin ich, geh' zur Ruh'… Gud som
hafver Barnen kär… Sun haltuus, rakas Isäni, ma aina annan itseni,
mun sielun' ruumiin', tavaran', ne ota Herra vastahan."
"Sen uskon ja sult' pyydän viel'."

*****

Kesäisin Katinka yhdessä Lenzyn ja Mirkan kanssa huvittelihe


pelkäämällä milloin mitäkin.

Pelko oli epäilemättä jotain erinomaisen hupaista. Se alkoi


suloisena, vihlaisevana hivelynä sydänalassa ja levisi sitten kuin
kipinöinä sormenpäihin saakka. Se oli yhtä jännittävää, kuin mikä
muu leikki tahansa. Pääasia oli vain, että osasi pelastua viime
tingassa, silloin ei ollut mitään hätää.

Tiesiväthän he tietysti, etteivät suuret, hiljaiset kuvastimet


alasalissa, enemmän kuin yläkerran kaikukaan, joka heitä niin
kammotti, olleet millään lailla vaarallisia, niin kauan kuin antoi niitten
olla rauhassa. Omasta aloitteestaan ne eivät mihinkään ryhtyneet.
Ne olivat kuin nukkuvia, rauhallisia petoja, jotka kävivät uhkaavaksi,
vasta kun niitä uhitteli ja härnäsi.

Mutta sitä he juuri halusivatkin. He tahtoivat väkisinkin herättää


kaikki vihamieliset voimat, mitkä uinuivat peilien valhesyvyyksissä ja
yläkerran kaikuvissa lokeroissa, nauttiakseen omasta pelostaan.

Ja niin uudistui lukemattomia kertoja sama näytelmä: he marssivat


yläkerran portaita peräkanaa, juhlallisina ja varovaisina, edellä
kultatukkainen, totinen Lenzy, sitten pieni ja hento, raskasluominen
Mirka ja lopuksi Katinka. He pääsevät onnellisesti portaitten
kierrokseen saakka, puolipimeästä häämöittävät vastaan yläkerran
monet komerot.
Ne olivat täynnä lukinseittejä, paksuja nahkakantisia kirjoja,
käsittämättömiä metallitankoja, putkia ja pyöriä, joitten
tarkoituksesta heillä ei ollut aavistustakaan. Vanhan herran romua!
oli Sokia-Mari sanonut. Kerran he olivat eräästä nurkasta löytäneet
suunnattoman suuren pahvisen nukenpäänkin, jolla oli mustat,
oikeat kiharat, ja poven verhona purppuranpunainen silkinrepale.

Mutta he eivät peljänneet niinkään näitä komeroita. Oli jotain


muuta, mikä oli monta vertaa salaperäisempää. Vielä muutama
askel, ja koko yläkerta alkaa elää, joka nurkasta, lattiapalkkien alta,
seinänraoista valittaa kumea kaiku. Tätä hetkeä he ovat odottaneet.
Se on aivan lähellä heitä, he kuulevat sen vaikerruksen. He
syöksyvät suin päin alas, kompastuvat, kierivät pitkin portaita. Se on
heidän kintereillään, se ajaa heitä takaa alas asti.

Taikka he sytyttävät kaksi kynttilää alasalin seinänkorkuisten


kuvastimien eteen. Kynttilät palavat peilipöydällä, he istuvat kukin
kuvastimensa edessä. Silmiä ei saa räpyttää. Silmät väkinäisesti
avoinna he tuijottavat kuvastimen valhesyvyyteen. Silmät alkavat
vuotaa vettä, peilin pinta himmenee, alkaa kiertää kuin sekavaa
tähtisumua. Ja tähtisumusta alkaa haahmoittua outoja ja
eriskummaisia olioita, jotka panevat heidän sydämensä värisemään.

Mutta kun kauhu oli korkeimmillaan, he pidättivät hengitystään


eivätkä kirkaisseet, — he nauttivat omasta kauhustaan.

Mustalaisia he sensijaan pelkäsivät todenteolla, kuten vauhkoja


oriita tai raivokkaita härkiä. Niitä kulki pitkin kesää Hovin ohitse,
kaupungista päin tullen tai mennen, jalkaisin tai vankkureilla, suurina
parinkymmenen hengen saattueina. Hoviin saakka kuului maantieltä
heidän lastensa ja porsaittensa parku. Kaikki seitsemän
kuolemansyntiä mahtui heidän säkkeihinsä. He piileksivät
Revonkiven raossa ja Itkevällä Kalliolla, väijyen ohiajajia. He olivat
kiristäneet Herttualan maitokuskilta rahat. He varastivat lapsia,
värjäsivät niitten hiukset, pesivät naaman kahvinporolla, pistivät
pussiin ja inttivät porsaan kirkuvan. Ei koskaan voinut tietää, oliko
säkissä lapsi vaiko porsas. Ja Katinka tarkasteli murheissaan mustia
hiuksiaan ja ruskeaksi paahtunutta kaulaansa: hän olisi kelvannut
sellaisenakin, värjäämättä, mustalaisen säkkiin. "Mustalaisvekara!"
kivahti Annikin aina, kiukkuiselle päälle sattuessaan. Niin oli siis
juostava pakoon, jos kaukaa maantiellä näki vilahduksenkaan
mustalaisista. Mutta Hovin keittiössä saattoi heitä Annin hameitten
turvista katsella, kun he puoliväkisin työntyivät sisään, ensin aina
akat, sitten vasta miehet, ja mankuivat mangu, mangu maaraansa
tai sitten mielin kielin latelivat Kyökki-Ievalle: "hei herttasei, anna
leipää, anna kallaa… hei herttasei, anna voita…"

Kokonaan toista laatua oli ukkosilman ahdistus. Tuli joskus


yht'äkkiä hiostava helle, Hovi alavassa alhossaan hukkui kuin pätsiin,
kaikki hiljeni, ilma sameni raskaitten, hohtopalteisten pilvien alla
salaperäiseksi ja hiljaiseksi. Lakkasivat lepattamasta tammet ja
vaahterat ja haarakoivut. Kreikkalaistemppeli vain säteili yhä
valkoisempana kuin omaa valoaan.

Sitten kumeaa, pilvensisäistä jyminää. Kokonaiset pilvivuoret


halkeilevat Hovin päällitse ja paljastavat salamanvälkähdyksessä
hehkuvan sisustansa, joka on valkoista tulta. Satoi, suuret
vesisuihkut huuhtelivat yläparvekkeen asfalttia.

Mirka seisoi ikkunan edessä ja huusi: "Kuule, — kuinka Jumala


pauhaa!" Mutta Katinka sulki oven säppiin ja vielä lukitsikin sen, —
silloin ei ainakaan Jumala pääsisi sisälle. Hupussa, peiton alla hän
kuunteli pilvien räjähdyksiä ja näki salamat, vaikka ummistikin
silmänsä. Hän ajatteli vanhaa herraa, joka haulikko kädessä uhmasi
ukkosta ja jylyä.

"Minä olen hänen tyttärensäpojantytär…" hän sanoi, — "hänen


tyttärensäpojantytär, — vanhan Fataburin, Hovin vanhan herran…"

Enimmän kuitenkin Katinka kesäisin leikkisiskoineen pelkäsi


Vanhaa-Kuningasta, lampuodin, nuoren Kuninkaan, isää, joka istui
akaasia-aidan toisella puolen, ainaisessa tukituolissaan, kivenheiton
matkan päässä Hovin päärakennuksesta ja pylväsportaikosta. Vanha-
Kuningas pysytteli parhaasta päästä huoneessaan, mutta kauniilla
säällä hänen vaimonsa ja poikansa kantoivat hänet ulos
auringonpaisteeseen. Hän oli vastenmielinen katsella. Hänen
silmänsä, suuret ja lasittuneet, olivat avoinna, mutta muuten hän oli
pikemmin kuollut kuin elävä. Hänen suuri ja pöhöttynyt ruumiinsa,
jonka halvaus oli kytkenyt liikkumattomuuteen, täytti koko tuolin,
kuten kömpelö, mudankarvainen virtahirviö. Hänen monenkertainen,
velttolaskoksinen leukansa riippui syvälle rintaa vasten painuneena.

Hovin lapset kurkistelivat häntä akaasioitten takaa kuin


kummitusta, uteliaina, mutta ilman vähintäkään sääliä. "Hän on
paha", päätteli Katinka järkkymättömällä varmuudella, ja sillä oli
Vanhan-Kuninkaan tuomio lausuttu. Kuinka hän olisi voinut olla
muuta kuin paha! Hänen hyllyvät, vihertävät kasvonsa ja liikkumaton
ruumiinsa eivät näyttäneet olevan missään tekemisissä hyönteisten
surinan, pääskysten lennon ja sireenin tuoksun kanssa, joka häntä
ympäröi. Hänen jaloissaan käyskentelivät muurahaiset, mutta hän ei
tiennyt siitä. Hän oli vain kuin sadut Pahasta-Kuninkaasta,
kummallinen ja rujokas kuva jostain ammoin revitystä kuvakirjasta.

Ja sittenkin oli hänellä käsissään vielä liikuntakykyä ja voimaa.


Vanhalla-Kuninkaalla oli nahkahihna, jolla hän tarpeen tullen kuritti
lapsiaan ja lapsenlapsiaan, pitääkseen heidät Herran pelvossa ja
nuhteessa. Yöjuoksua hän ei sallinut, se oli sanottu, — ei! Hän oli
ilkeäsisuinen ja häijy. Hän sivalsi nahkahihnalla nuorta, kaunista
tytärtään, jonka mieli paloi syntiin ja tansseihin. Hän oli
kuninkaantytär, mutta sai maistaa nahkahihnaa.

Paitsi sitä oli Vanhalla-Kuninkaalla aina vieressään tuolin nojalla


ryhmysauva, jolla hän koputti, jotain tarvitessaan. Ja Katinkan valtasi
outo ja syntinen halu: kunpa Vanha-Kuningas yht'äkkiä tarttuisi
ryhmysauvaansa ja hyökkäisi heitä takaa-ajamaan. Oh, kuinka he
juoksisivat, kuinka he juoksisivat! Aina Tilkoanniemelle asti ja sitten
yhä ympäri, yhä ympäri pyörötemppelin, ja orjantappuran piikit
pistelisivät Pahaa-Kuningasta sääriin. Ja Paha-Kuninas huohottaisi:
kyllä saan teidät kiinni, — kyllä saan teidät kiinni, tyttöletukat! Mutta
samalla he hypähtäisivät yli sillan kaidepuun ja katoaisivat valkoisina
hiirinä kivien koloon.

He tekivät pillejä akaasian paloista ja viheltelivät härnätäkseen


Vanhaa-Kuningasta. Mutta Vanha-Kuningas ei suvainnut
hievahtaakaan eikä kunnioittaa heitä vihallaan eikä
suuttumuksellaan. Hän säästi sen nähtävästi omille jälkeläisilleen.
Kärpäset kävelivät kaikessa rauhassa pitkin hänen kasvojaan, kunnes
tuvasta tuli hänen vanha vaimonsa, jolta pillastunut orhi aikoinaan oli
potkaissut nenän murskaksi, ja ajeli lehvällä kärpäset pois.

Mutta iltaisin, — ja sen taisi kuulla Hovin portaille saakka, —


jymisytti Vanha-Kuningas kaikuvasti ja äkäisesti ryhmysauvaansa
lattiaan, kun nuori Kuninkaan-Kati oli hiipinyt Hovin-Annin ja kauniin
Sisä-Miinan kanssa Porkansaaren poikien tansseihin Tilkoanniemen
pyörötemppeliin, kengät ja sukat kainalossa ja päähuivi kätkettynä
povelle.
14.

Juuri Tilkoanniemen roomalaisessa pyörötemppelissä, missä


Fatabur aikoinaan oli istutellut paimeniaan ja paimenettariaan,
tapahtui sitten tänä kesänä Katinkan ja Mykkä-Salamonin kohtaus.

Heti Hovista maantielle päästyä oli kaupunkiin mennessä


Ahokkaan kylä. Se kuului naapurihoviin, ja oli, kuten hovien kylät
ainakin, huonosti rakennettuja, harmaita tai punamullalla sivuttuja
mökkejä, joissa asui kaikenkarvaisia pien'eläjiä, — sepästä alkaen,
jonka paja oli heti tienristeyksessä. Suurin osa mökeistä oli
siunaantunut runsailla lapsilaumoilla, ja näitä Ahokkaan
paljaskinttuisia, repaleisia lapsia liikeni kaikkialle. Heidän vakinainen
leiripaikkansa oli Vainikan tien risteys, josta maantie kääntyi
kaupunkiin; siellä olivat heidän pyöreistä mukulakivistä kyhätyt
lehmitarhansa käpylehmineen; paitsi sitä tähystyskivi, josta saattoi
pitää silmällä sekä kaupungin että Tervajoen puolen ja samalla
kaiken, mitä Hovissa tapahtui.

He muodostivat ikäänkuin kaikkien Hovissa tapahtuvain


näytelmäin katsojajoukon, yhdessä Hovin omien alustalaisten
kanssa. Sisimmässään he varmaan olivat vakuutetut siitä, että kaikki
nämä näytelmät oli pantu toimeen heidän erikoiseksi
hauskutuksekseen, talkoot, kesäiset vieraspidot. Heidän isillään ja
äideillään oli epäilemättä ollut enemmän tuijotettavaa vanhan
Fataburin aikoina, nykyisten Ahokkaan lasten riemuksi sai riittää
maantiellä ajavat kaleskat tai umpivaunut. He ilmestyivät
tienristeykseen kuin varpusparvi, niin pian kuin kuulivat vaunujen
töminän. Alkoi kilpajuoksu: he kirmasivat vaunujen jäljessä aina
vaahterakujalle asti, koko ajan sakeassa tomupilvessä. Sattui, että
heille heitettiin kourallinen vaskilantteja, silloin syntyi maantien
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebooknice.com

You might also like