100% found this document useful (6 votes)
46 views

Download Complete Foundations of Linux Debugging, Disassembling, and Reversing: Analyze Binary Code, Understand Stack Memory Usage, and Reconstruct C/C++ Code with Intel x64 1st Edition Dmitry Vostokov PDF for All Chapters

Reconstruct

Uploaded by

ussieldeiicy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (6 votes)
46 views

Download Complete Foundations of Linux Debugging, Disassembling, and Reversing: Analyze Binary Code, Understand Stack Memory Usage, and Reconstruct C/C++ Code with Intel x64 1st Edition Dmitry Vostokov PDF for All Chapters

Reconstruct

Uploaded by

ussieldeiicy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Foundations of Linux Debugging, Disassembling, and


Reversing: Analyze Binary Code, Understand Stack
Memory Usage, and Reconstruct C/C++ Code with
Intel x64 1st Edition Dmitry Vostokov
https://ebookmass.com/product/foundations-of-linux-
debugging-disassembling-and-reversing-analyze-binary-code-
understand-stack-memory-usage-and-reconstruct-c-c-code-with-
intel-x64-1st-edition-dmitry-vostokov/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


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

Foundations of ARM64 Linux Debugging, Disassembling, and


Reversing: Analyze Code, Understand Stack Memory Usage,
and Reconstruct Original C/C++ Code with ARM64 1st Edition
Dmitry Vostokov
https://ebookmass.com/product/foundations-of-arm64-linux-debugging-
disassembling-and-reversing-analyze-code-understand-stack-memory-
usage-and-reconstruct-original-c-c-code-with-arm64-1st-edition-dmitry-
vostokov/
ebookmass.com

Foundations of ARM64 Linux Debugging, Disassembling, and


Reversing Dmitry Vostokov

https://ebookmass.com/product/foundations-of-arm64-linux-debugging-
disassembling-and-reversing-dmitry-vostokov/

ebookmass.com

Fundamentals of Trace and Log Analysis: A Pattern-Oriented


Approach to Monitoring, Diagnostics, and Debugging 1st
Edition Dmitry Vostokov
https://ebookmass.com/product/fundamentals-of-trace-and-log-analysis-
a-pattern-oriented-approach-to-monitoring-diagnostics-and-
debugging-1st-edition-dmitry-vostokov-2/
ebookmass.com

Comprehensive Materials Finishing 1st Edition Saleem


Hashmi

https://ebookmass.com/product/comprehensive-materials-finishing-1st-
edition-saleem-hashmi/

ebookmass.com
Oxide Electronics 1st Edition Asim K. Ray

https://ebookmass.com/product/oxide-electronics-1st-edition-asim-k-
ray/

ebookmass.com

Behavioral and Mental Health Care Policy and Practice: A


Biopsychosocial Perspective – Ebook PDF Version

https://ebookmass.com/product/behavioral-and-mental-health-care-
policy-and-practice-a-biopsychosocial-perspective-ebook-pdf-version/

ebookmass.com

How Things Count As The Same: Memory, Mimesis, And


Metaphor Adam B. Seligman

https://ebookmass.com/product/how-things-count-as-the-same-memory-
mimesis-and-metaphor-adam-b-seligman/

ebookmass.com

Practitioner's Guide to Operationalizing Data Governance


Mary Anne Hopper

https://ebookmass.com/product/practitioners-guide-to-operationalizing-
data-governance-mary-anne-hopper/

ebookmass.com

P.O.W.E.R. Learning: Foundations of Student Success 4th


Edition Robert Feldman

https://ebookmass.com/product/p-o-w-e-r-learning-foundations-of-
student-success-4th-edition-robert-feldman/

ebookmass.com
Wrongful Convictions and Forensic Science Errors: Case
Studies and Root Causes John Morgan

https://ebookmass.com/product/wrongful-convictions-and-forensic-
science-errors-case-studies-and-root-causes-john-morgan/

ebookmass.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
Random documents with unrelated
content Scribd suggests to you:
are too obscene to be sung to-day in their old form by refined
society, but after their new baptism by Burns, they have become
teachers of piety that excel in lasting power preachers or sermons.
Such, for example, is “John Anderson, my Jo, John,” now so sweet
and pathetic. In fact, Burns’s transformation of certain specimens of
Scottish song is like that which we have seen when a handful of
jewelry, of fashions outworn, was cast into the crucible made white
hot and salted with nitre. The dross went off into vapor and fumes
and the old forms and defects were lost in oblivion. What was of
value remained. The pure gold was not lost, rather set free and
regained. Poured forth into an ingot, that would become coin or
jewels, it entered upon new life and unto a resurrection of fresh
beauty.
Above all, Burns disliked to be tutored in matters of taste. He
could not endure that one should run shouting before him whenever
any fine objects appeared. On one occasion, a lady at the poet’s
side said, “Burns, have you anything to say to this?” He answered,
“Nothing, madam,” as he glanced at the leader of the party, “for an
ass is braying over it.”
Since the ploughman-poet of Ayr was so generous in confessing
inspiration and indebtedness to his greatest teacher, it is not meet
that we should ignore this man and name in any real view of the
forces making intellectual Scotland.
Robert Fergusson, though less known in countries abroad than
in Scotland, was the spiritual father of Robert Burns and none
acknowledged this more than Burns himself. When the man from Ayr
visited Edinburgh, in 1787, he sought out the poet’s grave and
erected the memorial stone which is still preserved in the larger and
finer monument. Fergusson, born in 1751, was a graduate of St.
Andrews. In Edinburgh, he contributed poems to Ruddiman’s
“Weekly Magazine,” which gained him considerable local reputation.
His society was eagerly sought and he was made a member of the
Cape Club. Unfortunately, Fergusson fell a victim to his convivial
habits, and was led into excesses which permanently injured his
health. Alcohol probably helped to develop that brain disease usually
called insanity. It was while in this condition that he met with Dr. John
Brown, of Haddington, whose name is a household word in Scotland.
The good man, a sound Presbyterian and Calvinist, was much more.
He made “the love of the Lord” the real and ultimate test of a man’s
orthodoxy. Brown’s “Self-Interpreting Bible” has been amazingly
popular throughout heather land. The John Brown, whom some of us
knew, who wrote “Rab and His Friends,” and “Pet Marjorie,” was the
grandson of Fergusson’s friend.
After meeting with Dr. Brown, Fergusson became so very
serious that he would read nothing but his Bible. A fall, by which his
head was seriously injured, aggravated the symptoms of insanity,
which had already shown themselves. After two months’
confinement in the only public asylum then known in Edinburgh, he
died in 1774. His poems had been collected the year before his
death.
Perhaps Fergusson’s fame rests as much upon his unhappy life
and early death, and upon the fact that he was a true forerunner of
Scotland’s greatest son of genius, as upon the essential merits of his
verse. Burns read carefully Fergusson’s poems, admired them
greatly, and called the author his “elder brother in the muses.” The
higher critics declare that his influence on the poems of Robert
Burns, such as “The Holy Fair,” “The Brigs of Ayr,” “On Seeing a
Butterfly in the Street,” and “To a Mouse,” is undoubted. Even “The
Cotter’s Saturday Night,” when read alongside of “The Farmer’s
Ingle,” of Fergusson, shows that Burns’s exquisite picture in verse of
homely peasant life in Scotland is a firelight reflection of the older
original, at which Burns warmed his genius.
With less of an immediate intellectual debt, Burns was certainly
obligated to an older cultivator of Scottish poetry; who, in large
measure, must be credited with the revival of public appreciation of
the bards of Caledonia and who helped powerfully to create the
climate in which Burns’s genius could blossom and bear fruit.
Among the effigies in Edinburgh, city of statues, is that of Allan
Ramsay, the poet (1686–1758). When we first saw this work of art, it
was comparatively new, having been erected in 1865, by which time
national appreciation had ripened.
Ramsay must ever hold the gratitude of Scottish people,
because he, more than any one else, made the wonderful world of
Scottish music known in England and to the nations. He brought
together, in “The Tea-Table Miscellany,” a collection of the choicest
Scottish songs. He himself was a poetaster, rather than a great lyrist,
and throughout his career proved himself a canny business man.
In literary history Allan Ramsay achieved two great triumphs. He
contributed thus early to the naturalistic reaction of the eighteenth
century against the slavery to classicism. As an editor, he furnished
the connecting link between the “Makars,” as verse-writers were
called in the Scotland of the fifteenth and sixteenth centuries, and
the poets Fergusson (1751–74) and Burns (1759–96). Ramsay did
much to revive interest in vernacular literature. He certainly
stimulated an ignorant public to fresh enjoyment.
This reaction in Scotland was followed by one in England, for
which the publication of Bishop Percy’s “Reliques of Ancient English
Poetry” furnished a sure foundation. Scotland honored herself when
she honored her poet Ramsay. Happy is the nation that appreciates
her sons who bid her people look within to find enduring treasure. To
Ramsay, the prophet’s words apply: “And they that be of thee shall
build the old waste places; thou shalt raise up the foundations of
many generations and thou shalt be called ... the restorer of paths to
dwell in.”
The second Allan Ramsay (1713–84), an accomplished scholar
and gentleman, was the son of the poet. Being carefully educated by
his father and sent to Rome to study art, he became an able portrait-
painter. Through introduction to the Prince of Wales, afterwards
George III, he rose rapidly into favor. To him we are indebted for the
portrait of that King George, with whose physiognomy, more than
with that of almost any other sovereign of England, our fathers
became very familiar during the time of their eight years’
disagreement with His Majesty and his ministers.
CHAPTER XXII
KIRK, SCHOOL, AND FREEDOM

A visit to St. Andrews, the home of golf and of ancient and


modern Scottish culture, compels thought. I have met Scotsmen who
thought and devoutly believed that there was nothing among all the
lands of earth equal to Scotland, and in Scotland nothing greater
than the Kirk. Yet this stout insistence has come not alone from
believers in “the old gospel,” so called, but with equal vehemence
and cool conviction from men saturated with the philosophy of
common sense, even from those fearing not to be called
“freethinkers.” The real Scotland, like the true United States
described in Whittier’s verse, seems to fear neither “the puny
sceptic’s hands” nor “the bigot’s blinded rule.” At least, her history
teaches this.
The first heralds of the new dawn, whose advent awakened
Scotland from her mediæval slumber of intellect, were the Lollards of
Kyle, who were among our own spiritual ancestors. They made a
great excitement in western Scotland in the early part of the fifteenth
century. Their coming was as refreshing as when a window is
opened in a stuffy room, letting in God’s fresh air. The articles of
which the Lollards were accused, as Knox found them stated in the
Register of Glasgow, make us love these people, for their faith and
belief were very much like what is held by the mass of the people
who live and think in northern Europe and in the United States of
America to-day. Some things to which they held are still retained by
Christians who are as wide apart as are Quakers and Catholics.
Those who cut down the forest are often surprised at the new
and different timber which springs up from the soil. After John Knox,
David Hume! But if the Puritans and reformers had not been
intolerant, they would not have been men of their own age. It is to
the glory of these narrow-minded but high-souled men that they
believed in education. They could not well conceive that any other
belief was as good as their own. Yet theirs was not the spirit of
Mahomet, who gave choice of acceptance of sword or creed; for
these men, who had a conviction themselves of the truth, demanded
from others the same knowledge, by experience and enlightenment,
of these doctrines which they believed. Hence they were earnest for
both elementary training and the higher erudition.
If living to-day, the spiritual pioneers and reformers would no
doubt be surprised at the visible harvest. Yet it was their opening of
dark places to the light, through the cultivation of the mental soil, that
made the intellectual landscape which we see to-day. The Indians
call the plantain the “white man’s footstep,” because they note that
the cutting-down of the dark forests and opening the soil to the
sunlight have given the weeds also their opportunity; so that, far
more numerously than in the twilight of the woods, or even in the
little clearings for the corn and pumpkins, the highways and fields
are to-day populous with what we call “weeds.” Yet how vastly
greater is the crop of what makes food for man! This is the story,
also, of intellectual culture in every age and land. Perhaps it always
will be thus. The best of all practical philosophy on this subject is that
taught by the greatest of teachers—“let both grow together.”
Persecutors, bigots, and tyrants have acted in a different spirit, with
appalling results.
The Reformation was more of a success in Scotland than in
England, even as men are of more value than edifices of brick and
stone, and the people of more value than courts. It culminated, in the
lower part of the island, in the divine right of kings and the celestial
origin of the Established Church, for Elizabeth was advised by Spain
and was strong enough to prevent any open change. But north of the
Tweed the people were more generally educated and elevated to a
higher place. Hence, in Scotland there was no such tempest raised
as there was in the next century, in England, when one king was
decapitated and another sent out of the kingdom. Scotland saved
herself from stupid kings and a multitude of horrors by previously
giving her people the rudiments of knowledge. We in America have
never had, from English writers, either fair play or full truth about the
Scots, nor is the Scotsman’s part in the making of the United States
generally appreciated. The Scotch Puritans not only exercised a
marked and lasting influence upon their brethren in England, but
upon those beyond sea. Next to the Hollanders, who taught us
Americans pretty much all we know of Federal Government, was the
influence of Scotsmen in the development of the American nation.
The Normans gave to England her universities, her cathedrals,
and her legal system, but Scotland never shared in the benefits of
the Norman invasion as did England. One may almost say that in
place of the nobler and creative side of the Norman genius was
Presbyterianism; that is, representative and responsible government
in the Church, the actual rule being by lay elders chosen by the
congregation. Much of this republicanism in things religious was the
work of one man, the greatest in a country prolific of great men as
Scotland has been. John Knox’s power was resistless, because he
trusted in God and in the common man.
It is astonishing how much alike William the Silent, John Knox,
and Abraham Lincoln were in putting confidence in the plain people.
William of Orange, the great moderate man of the sixteenth century,
found that kings and princes were as reeds to lean upon, nobles
were selfish and factious, but that the common people, when you put
confidence in them, could be trusted. John Knox walked in the
footsteps of William of Orange. Lincoln followed Knox.
Yet Knox was not the founder of the Scottish Reformation, which
had begun before he had left the old Church; he was its nurse, not
its parent. At first the Reformation in Scotland, as in some parts of
Europe, was a political, not a religious movement. In the beginning
the Scotch nobles hoped to be enriched from the Church lands, as
their peers in England had been; but among the Scottish people
there were gradually formed circles in which education of mind and
heart went on. Apart from the court and nobles, the people wanted a
change for the better. This general intelligence among “the
commonalty” had already so undermined the structure of the old
political Church in Scotland that when Knox blew his bugle blast, this
semi-political edifice came tumbling down.
In two hundred years Scotland made more progress than any
other country in the world. Her people, in proportion to their
numbers, have probably done more for the general advancement of
the race than those of any other modern nation. Yet the foundation of
Scotland’s prosperity was laid by John Knox and his successors.
Hamerton, who wrote that charming book, “A Painter’s Camp in the
Highlands,” said in one of his works that, in proportion to their small
numbers, the Scots are the most distinguished little people since the
days of the ancient Athenians, and the most educated of the modern
races. “All the industrial arts are at home in Glasgow, all the fine arts
in Edinburgh, and as for literature it is everywhere.”
Twice the Scots signally nullified the ambition of kings. Edward I,
whom the English count one of their greatest kings, conquered
Wales and made it a permanent part of the British Empire. He
thought he had done the same thing with Scotland, but there he met
a different foe, and twenty years later, Scottish valor at Bannockburn
gave Scotland her independence forever. How strange that this
same reign saw the death of Roger Bacon, the culmination of
Christian architecture, and the expulsion of Jews from England!
When King James came to London, in 1604, he found himself in
such a totally different atmosphere that he tried to use the power of
England behind him to force the rule of the bishops, in place of
elders, upon his Scottish subjects. In England the Church lords told
King James, when discussing religious matters, that he was inspired
of God. Those who have read the disgustingly fulsome praise of King
James, made in their preface by the translators of the English Bible
in 1611, can see that they believed in the divine right of kings. On the
contrary, in 1596, Andrew Melville, the preacher, in a public
audience, called James VI “God’s silly vassal.” Said he to him, “I tell
you, sir, there are two kings and two kingdoms in Scotland. There is
Christ Jesus the King, and his kingdom the Kirk, whose subject
James VI is, and of whose kingdom, not a king, nor a lord, nor a
head, but a member. And they whom Christ hath called to watch
over his Kirk and govern his spiritual kingdom have sufficient power
and authority to do so both together and severally.”
The Scottish commons, as Froude says, are the sons of their
religion, and they are so because that religion taught the equality of
man.
The literature of the subject of the relation of the king to the
people, which now holds its place triumphantly in England, shows
that this theory, regnant in the twentieth century, originated and was
elaborated in Scotland. The idea that the royal government arises
from popular electoral choice, and that for a king to break his part of
the contract makes him forfeit his right and justifies war against him,
—which has always been the American idea,—was first wrought out
in Scotland. The true theory of the relations between a king and his
subjects first appeared in a book published in Edinburgh, in 1580. It
was written by George Buchanan, and was the same that was
burned by Englishmen at Oxford in 1683.
It was not until 1594 that Hooker, in his “Ecclesiastical Polity,”
developed the idea of a social compact, which later was expanded
by John Locke, who was so much read by our fathers. Yet even
before Buchanan, French writers had discussed the rights and duties
of kings on the same democratic lines, and William of Orange, in his
“Apology” of 1570, had lengthily exploited the idea and demonstrated
in his life the right to take up arms against princes who abused their
trust. The “Apology” was but the preface to the Dutch Declaration of
Independence in July, 1581—the political ancestor of ours of 1776.
One who would find out and appraise with exactness the
influence of Scotland upon English thought, previous to the
eighteenth century,—that is, during the period of the colonization of
New England, before the Commonwealth, and later, when American
institutions were taking definite form,—will not find much to the point
in English books or documents. That Scottish writers and preachers
were most influential with English Puritans—the same who settled
America—cannot be gainsaid.
Neither can it be denied that Puritanism took on some dark and
unlovely forms. Yet we must remember that the work of Claverhouse
and the massacres of Scottish Christians by Englishmen were taking
place within a few score miles of these very people who first left
England, to find a permanent home beyond the Atlantic. These
English Puritans got their idea of the equality of man and that sense
of human dignity, which lies at the foundation of civil liberty, in large
measure from the Scots, who had already shown their hatred of
oppression and their contempt for differences of rank founded only
on the accident of birth.
From such a soil of history and feeling sprang Burns’s inimitable
poem, “A man’s a man for a’ that,”—the consummate white flower of
the poetry of humanity. It is barely possible that such a poem might
have been written in England in the eighteenth century, but, as a
matter of fact, it rose out of the heart of a Scotsman. In England the
lesson of the equality of man has not, even yet, been fully learned. In
America, it is the very foundation on which our Government rests.
Abraham Lincoln’s Gettysburg Speech is the answering and
antiphonic call to the song of Burns. In fact, we cannot understand
how any true history of the United States can be written which
neglects the study of Scotland’s history.
The Scottish people called those prelates appointed by the
London Government, who collected the revenues of their sees and
turned them over to their patrons, “tulchan” bishops. These prelates
got their nickname in Scotland from calfskins, stuffed with straw to
make them look like cow’s babies, with which the dairymen deceived
refractory cattle,—mothers that refused to give down their milk. In
1578, the General Assembly resolved that bishops should be called
by their own names and not by their titles or sees, and that no vacant
see should be filled until the next December. In 1580, the whole
system was abolished when the General Assembly, meeting at
Dundee, resolved that the office of bishop was a mere human
invention unwarranted by the Word of God.
The custom of British peers signing only their surnames, or by
peerage designations, though no older than the times of the Stuart
kings, has been imitated by the prelates even on hotel registers. This
fashion of using geographical affiliations with their surnames only
had an amusing illustration while we were in Scotland. A certain
American bishop from our neighborhood, travelling through Europe,
subscribed himself, let us say, as “Theophilus of Peoria.” By
accident, this worthy man of God was followed around by a
clergyman of Scottish descent, who was not loath, for the sake of a
good joke, to imitate the example of so noble a son of the Church.
He made his sign manual, let us say, as “Bartholomew of Pony
Hollow.”
Happily in these our days the Scots and English, though so
different in old and fundamental ideas, have come to work hand in
hand together in civil government. Even within the fold of salvation,
they dwell in Christian charity, ever agreeing to differ—the
Episcopalian in Scotland being a “Dissenter” and the Scotch
Presbyterian in England the same, each being in his own country a
“Churchman,” while the average American is amused at the whole
proceeding. With what a hearty roar of merriment a party of us
Bostonians, when we saw it, bought, for the fun of the thing, a
photograph, of cabinet size, found in the London shop windows, of
our neighbor, friend, and fellow Christian, the “Lord” Bishop Phillips
Brooks, of Yankee land and Hub fame and beloved by all men. Think
of an American shepherd of God’s heritage “lording” it over the flock!
Yet we forgave the English printer, who probably never noticed his
own joke, or knew how funny he had made himself to Yankees.
A survey of Scottish religious history, such as Melrose, Iona, and
St. Andrews suggest, shows that in the first working-out of the
human spirit, as it reacted upon form and symbol and developed in
submission to discipline and the law of unity, the Scottish churches,
of necessity, followed the rule of Rome. The flowering of the human
spirit, in the hewn stone of church and abbey, took on forms of
beauty akin to those in the south, yet with Gothic luxuriance. The
marble blossomed in air as from the native rock, and the artist’s
chisel made gardens of beauty. Wonderful and alluring was the
reality of the mediæval landscape, gemmed with richest architecture
and wealthy in sacred edifices made beautiful with color, carving,
gems, and the gifts of the devout, the travelled, and the wealthy. The
graceful edifices, the abbeys and monasteries, the parish churches,
the tithe-barns, the castles and bishops’ seats, made even this far
northland a region of charm and romance. Within these sacred walls,
what impressive chants and processions, incense and lights, and all
that resplendent paraphernalia of robed and costumed ministers of
religion, which, whether in pagan or Christian lands, do so appeal to
the senses in spectacular worship!
All this mediæval, dramatic variety, so strongly set in contrast to
the simplicity of worship to-day, did, in a certain sense, correspond to
the contemporaneous glory of civil and military splendor of feudal
days. Then the pageant of the titled knight, in shining steel upon his
proud steed, leading his clansmen in their brilliant tartans, with
claymore and target,—with a rich background of the visible splendor
of castles, lords and ladies, in that feudal life which Scott has
idealized, glorified, yes, even transfigured in his poetry and
romances,—was matched by outward ecclesiastical magnificence;
both systems making irresistible appeal to the senses and both
being equally far removed from the primitive simplicity of the Master
and his disciples.
In a word, Christianity in Scotland wore the garments of the
civilization of the age during which it took on its material forms,
changing its outward habiliments as its growing spirit entered more
deeply into the old, unchangeable truth. In the case of certain young
nations, having characteristics that respond to what is first offered
them, and in which native traits can make subtle harmony with the
imported religion, history marks out but one course—the standards
of religion and civilization usually run in parallel lines.
CHAPTER XXIII
JOHN KNOX: SCOTLAND’S MIGHTIEST SON

Scotland began the active and aggressive Protestantism of


Europe. The people, taught by John Knox, led the nations in taking
radical measures to apply the principles of democracy, developed by
George Buchanan, to the government of the Christian Church. In a
word, the Scottish people, and not their kings or nobles, reformed
religion and were leaders in social reconstruction.
John Knox would not have been a Scotsman if he had not, when
his mind had been changed through the study of the Bible and the
writings of Augustine and Jerome, gone at once to the extreme of
opposition. He preached first to the soldiers in the garrisons of St.
Andrews. Taken prisoner by the French fleet, he spent nineteen
months as a galley slave, often in irons and treated cruelly.
Meanwhile Providence shaped events that were to influence
America and her future.
It seems strange to us of to-day to think that any one in colonial
America should ever have had a fear of sharing a fate like that of
John Knox in the French galleys; yet from the time of the first
colonies of French Huguenots in Florida, down to the assertion, by
Jacob Leisler, of the people’s rights in New York, there were tens of
thousands among the several nationalities that made up the
American people who felt this danger, from the Bourbons of France
or Spain, as a quite possible reality. History makes strange
somersaults. In seeking our American freedom in the Revolution, we
were militarily aided by the former country and were in alliance with
the latter.
Knox, the one man able to stand up against Queen Mary, was no
amateur statesman or ecclesiastic. Besides his education in the
University of Glasgow and the regular training in the priesthood, he
had spent five years as preacher, pastor, and pioneer of English
Puritanism in England,—at Berwick, at Newcastle, and in London,—
where he married Marjorie Bowes and by her had two sons. He was
elected one of the six chaplains of Edward VI and was consulted
about the Anglican Articles of Religion, and the Revision of the
Liturgy. The king offered him the bishopric of Rochester, but he
declined for reasons of conscience, not only because he was
opposed to the secular business of such offices, but chiefly because
in his heart he believed, like the Independents, in what our own
Rufus Choate called “a church without a bishop and a state without a
king.”
When the English Queen called “Bloody Mary” came to the
throne and the Reformation seemed like a sinking ship, Knox was
the last to leave the deck, yielding only to the urgency of his friends.
Except more than half a year in Scotland, he spent five years on the
Continent. In Geneva, while sitting at the feet of John Calvin,—that
great champion of democracy and of republican government, and
the real father of the public school system,—he became pastor of a
church of English exiles there, and had a hand in making the
Geneva version of the Bible.
He who, whether of the old faith or the new, or an adherent of
any church or religion, whether Jewish, Mahometan, Buddhist, or
Christian, looks only on that side which agrees or disagrees with his
own opinions and cannot see beyond, misses most of the lessons of
history. Whether we love or hate John Knox, we cannot shut our
eyes to what he did, both for popular education and to give Great
Britain linguistic unity. He made English the language of literary and
scholarly Scotland. It was his thorough knowledge of the English
language and his choice and use of it that regulated Scottish speech
and paved the way for the oblivion of the Gaelic. In both the written
and the spoken form of the English language, he followed the best
standards.
When Queen Elizabeth came to the throne, she refused Knox
passage through her dominions. He had already published his “First
Blast of the Trumpet against the Monstrous Regiment of Women,”
which was aimed at the misgovernment of two females, Bloody Mary
of England and Mary Queen of Scots. For this, Elizabeth never
forgave him. Those who insist, according to notions that have been
set forth in literary form, that Elizabeth was only a male creature, a
mere man in disguise, may perhaps find their contention weakened
by the treatment of Knox by Queen Bess.
Knox is even less likely to be forgiven in an era of suffragettes
and agitation of votes for women. Yet it must be remembered that
while Knox was too manly to retract, because he believed what he
wrote and retained his opinions on this subject to the last, yet he
never published his intended second or third “Blast,” nor ever
wished, in any way, to obstruct the path of Elizabeth. Yet at this time
he was in possible danger of the headsman’s axe.
In Scotland he married Margaret Stewart, of a noble family, and
by her had three daughters. In his native land he spent twelve years
devoted to the fierce struggle and triumph of the Reformation. On his
deathbed he could say before God and his holy angels that he had
never made merchandise of religion, never studied to please men,
never indulged his private passions, but faithfully used his talents to
build up the Church over which he was called to watch.
Dr. Philip Schaff, the greatest Church historian whom America
has yet produced and possibly its most cosmopolitan scholar,
declares that Knox “was the incarnation of all the noble and rugged
energies of his nation and age, and devoted them to the single aim
of a thorough reformation in doctrine, worship, and discipline, on the
basis of the Word of God. In genius, learning, wealth of ideas, and
extent of influence, he was inferior to Luther and Calvin, but in
boldness, strength, and purity of character, fully their equal. He was
the most heroic man of a heroic race. His fear of God made him
fearless of man. Endowed with a fearless and original intellect, he
was eminently a man of action, with the pulpit for a throne and the
word for his sword.”
Carlyle wrote a monograph on the portraits of John Knox. He
severely characterizes that patriarchal, long-bearded, but stolid
picture of Knox, which has been reproduced in many books from the
Geneva edition of Beza’s “Icones.” In truth, we have often wondered
why most of the pictures of the old divines, handed down to us from
the days of cheap and rude wood-cutting and black-letter books,
were not used to frighten naughty children or placed as scarecrows
in cornfields. Some readers will recall what Hawthorne has said
about some of these worthy predecessors of ours, who lived during
what another son of New England has called “the Glacial Age.”
Carlyle believed that the Somerville portrait, “with a sharp, stern
face, high forehead, pointed beard, and large white collar was the
only probable likeness of the great reformer,” who had “a beautiful
and simple, but complete incompatibility with whatever is false, in
word or conduct, inexorable contempt and detestation of what in
modern speech is called humbug.”... He was “a most clear-cut,
hardy, distinct, and effective man; fearing God and without any other
fear.”
Knox was a statesman as well as a theologian, possessing rare
political sagacity and intuitive knowledge of men. Like St. Paul and
Calvin, he was small in person and feeble in body, but irresistible in
moral force.
The two sons of Knox, of his first wife, were educated at
Cambridge, but died young, without issue. Of his three daughters,
one, Mrs. Welch, gained access to the king to ask the royal
permission for the return to Scotland of her sick husband, who had
been exiled because of his Presbyterian convictions. James at last
yielded, on condition that she should persuade him to submit to the
bishop; but the lady, lifting up her apron and holding it toward the
king, replied, as her father would have done, “Please Your Majesty,
I’d rather kep [receive] his head there.”
James VI paid the brave woman’s father a high tribute when he
lifted up his hands and thanked God that the three surviving bairns of
Knox were all lasses, “for if they had been three lads,” said he, “I
could never have bruiked [enjoyed] my three kingdoms in peace.”
It is Knox himself who relates the four or five interviews which he
had with the graceful and fascinating queen, whose charms and
misfortunes will ever excite sympathy and set men, who argue from
opposite premises, keeping up their endless controversies about her.
A greater contrast of characters can hardly be paralleled in
history. The one intensely Scotch,—the right man in the right place;
the other intensely French by education and taste,—the wrong
woman in the wrong place. The one in the vigor of manhood, the
other in the bloom of youth and beauty. The one terrible in his
earnestness, the other gay and frivolous. The one intensely
convinced of God’s sovereignty, and therefore of the people’s right
and duty to disobey and depose treacherous princes; she thinking
him a rude fanatic and an impertinent rebel. He confronting a queen,
whom he considered a Jezebel, unmoved by her beauty, her smiles,
or her tears; she compelled to listen to one whom she dared not try
to destroy.
It seems a very shallow judgment upon Knox, to say that he was
a “woman-hater.” On the contrary, he was a lover of good women,
was twice married, and wrote letters of comfort to his mother-in-law.
The truth is that in matters of sin and punishment, right or wrong,
truth or falsehood, there was for him neither male nor female. Men
must judge John Knox as they must judge any and all who tower
above their fellows, remembering that for what he believed to be his
supreme duty to God and his Church, he made as full a sacrifice of
his own personal consideration as of others. Carlyle declares that no
matter how we may explain these interviews with Queen Mary, “not
one reader in a thousand could be made to sympathize with or do
justice to or in behalf of Knox.” Here, more than elsewhere, Knox
proves himself—and here more than anywhere bound to be so—the
Hebrew prophet in complete perfection.
One feature in the history of the Scottish conscience profoundly
affected American life in its colonial and formative stages—the
emphasis laid in the Kirk of Scotland on the National Covenants.
They were politico-religious agreements for the maintenance and
defence of certain principles and privileges. The idea was copied
from Jewish precedent. They originated in that critical period when
the sacred rights and convictions of the people were in imminent
danger and when the religious and national sentiments were
inseparably blended. They were meant to defend the doctrine and
polity of the Reformed Kirk against all hostile attempts from within
and from without, and the sentiment of those who made them was to
die rather than to surrender. One can trace in these historical
movements of the Church three periods: (1) against the Papacy
(1560–1590); (2) against English prelacy (1590–1690); and (3)
against patronage, until 1875.
This custom of “covenanting” had a great influence upon those
people in Britain who so largely helped to make American freedom,
the English Puritans and the New Englanders. To-day the
outstanding feature of the independent congregations of several of
the largest and most influential bodies of Christians in America is the
covenant, which is taken on uniting with the church. The covenant,
as the expression of the individual to his Creator and Redeemer,
takes the place of the confirmation vows which are customary in the
Lutheran and Anglican churches. The “covenant” was the core of the
Mayflower Compact and of the Pilgrim Republic.
Dr. Schaff thus draws the religious map of Scotland: “The
Puritans overthrew both monarchy and prelacy, but only to be
overthrown in turn by the nemesis of history.... Romanism in the
Highlands is only an unsubdued remnant of the Middle Ages, largely
reinforced by Irish emigrants to the large cities. Episcopacy is an
English exotic, for Scotsmen educated in England and associated
with the English aristocracy. The body of the people are
Presbyterians to the backbone.”
The weak point in the establishment, by Parliament in 1690, of
Presbyterianism in Scotland, was the degree of dependence upon
the State, which kept up a constant irritation, and which, from time to
time, led to the new secessions from the Established Kirk, down to
the great exodus of the Free Church in 1843. But these were not
new departures, but rather, like the sects in Russia, were simply
returns to the old landmarks.
We are often amused, when in Scotland, at the large number,
some twenty or so, of ways of being a Presbyterian. Yet, looking into
these variations of belief, we find that, whereas in other countries
these would simply be different schools or parties in the same
denomination, they gave rise in Scotland to separate ecclesiastical
organizations. Nearly all these differences turn on minor matters,
such as psalmody, patronage, and relations to civil government.
The tremendous earnestness, scrupulous conscientiousness,
and stubbornness, which clothe these minor questions with the
dignity and grandeur of fundamental principles, are highly amusing
to an outsider. Yet, in reality, they are but the shadows of a great
virtue, for religion in Scotland is something taken quite seriously.
Looking more profoundly under the surface of the wavelets of
difference between the sects, one finds that the deep-sea currents
meet and flow into a unity of resistless movement. Instead of
antagonism, there is harmony; and one must acknowledge that, in
the main, Scotland is marked for a type of manly, sturdy, God-
fearing, solid, persevering type of Christianity.
While Scotsmen are musing on what is deepest in man, the fires
of devotion burn brightly and the soul utters itself in song, so that
Scotland is not least among the nations in its repertoire of either
poetry or music.
“Why are the Scotch so different from the English?” is a question
often asked. In my view the roots of the difference are best
discerned in a critical study of the Reformation. In Scotland this great
movement of the human mind was far more consistent and radical
than in England, and it therefore affected all classes more
thoroughly. Even more than a knowledge of racial elements does an
examination of religion—the deepest thing in man’s soul—explain
the peculiarities of Scottish as compared with English life, character,
and temperament. England is politically free, but is socially
aristocratic. Scotland is democratic in church and society.
These historical facts are worth remembering, especially when
we reflect that the Lowlanders were of Teutonic stock, like the
English. In England politics controlled religion. In Scotland religion
controlled politics. Hence common schools were more general. The
leading figure was neither a bishop nor a king, but a plain presbyter,
John Knox. In England, Cranmer, who may be called the father of
the English Book of Common Prayer, was timid, cautious, and
conservative. Knox, the father of the public schools of Scotland, was
bold, fearless, and uncompromising. It is true that in England royalty
was an almost resistless force, while in Scotland it was but the
shadow of feudalism. During these times that tried men’s souls,
England had a wise queen, both forceful and successful, while
Scotland’s sovereign was a woman as remarkable for her blunders
as for her beauty and her misfortunes.
Though the Scottish renascence of learning was not so
noticeable as in some other countries, yet Scotland, like the
Netherlands, had its Erasmus. George Buchanan, educated in Paris,
was the tutor in Greek and Latin to Mary Queen of Scots, and her
son James. Yet, though learned, Buchanan sympathized with the
people. In his famous book, “De Jure Regni apud Scotas,” he did but
preach in advance the principles of the American Declaration of
Independence, that “governments exist for the sake of the
governed.” The paper on which this truth was printed was burned in
Oxford during the Restoration period under Charles II, together with
those works of John Milton on “Government” which fed the faith of
our fathers in the right of the people to govern themselves. Yet no
fire has ever yet been kindled which can destroy the truth on which
the Constitution of the United States rests. For the intellectual bases
of their freedom, Americans owe a debt to Scotland quite as great as
to Holland or England.
CHAPTER XXIV
INVERGOWRIE: IN SCOTTISH HOMES

We have many times and in many countries proved the measure


of truth that is contained in the quatrain which William Shenstone
wrote upon the window of a hostel:—

“Whoe’er has travell’d life’s dull round,


Where’er his stages may have been,
May sigh to think he still has found
The warmest welcome at an inn.”

The American traveller can also agree in part with Dr. Johnson
that “there is nothing which has yet been contrived by man by which
so much happiness is produced as by a good tavern or inn,” yet who,
except Leighton, that sunny soul, the principal of Edinburgh
University,—who was “not militant enough to please his fierce co-
presbyters,”—could say “that if he were to choose a place to die in, it
should be an inn”?
Our experiences of Scottish hotels, “temperance,” “hydro,”
ordinary, fashionable, rural, rustic, and what not, were almost
invariably pleasant, and our hosts were honest in their dealings; yet
in the many British homes in which we were guests the welcome
was so warm and the care taken of us so thorough, thoughtful, and
minute, that Shenstone’s verse seems to have in it more verbal
music than experimental reality. Leighton’s wish seems strange,
indeed, especially in the light of memory, when sickness, apparently
nigh unto the bourne of life, proved the depth of Scottish hospitality
and friendship.
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!

ebookmass.com

You might also like