Reverse Engineering for Beginners
Dennis Yurichev
Computers & Technology
Reverse Engineering for Beginners
Free
Description
Contents
Reviews


There are several popular meanings of the term “reverse engineering”:




  1. The reverse engineering of software: researching compiled programs;


  2. The scanning of 3D structures and the subsequent digital manipulation required order to duplicate them;


  3. recreating DBMS9 structure.



This book is about the first meaning. This is the Full version. It is approximately 6 times longer than the Lite version  which is intended for those who want a very quick introduction to the basics of reverse engineering. The full version covers the topics of: OllyDBG, GCC, GDB and IDA. There are also exercises, examples, etc.



Topics discussed: x86/x64, ARM/ARM64, MIPS, Java/JVM.



Topics touched: Oracle RDBMS, Itanium, copy-protection dongles, LD_PRELOAD, stack overflow, ELF, win32 PE file format, x86-64, critical sections, syscalls, TLS, position-independent code (PIC), profile-guided optimization, C++ STL, OpenMP, win32 SEH.



Also in Russian.

Language
English
ISBN
0262033844
I Code patterns
A short introduction to the CPU
A couple of words about different ISAs
The simplest Function
x86
ARM
MIPS
A note about MIPS instruction/register names
Hello, world!
x86
MSVC
GCC
GCC: AT&T syntax
x86-64
MSVC—x86-64
GCC—x86-64
GCC—one more thing
ARM
Non-optimizing Keil 6/2013 (ARM mode)
Non-optimizing Keil 6/2013 (Thumb mode)
Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
Optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
ARM64
MIPS
A word about the "global pointer"
Optimizing GCC
Non-optimizing GCC
Role of the stack frame in this example
Optimizing GCC: load it into GDB
Conclusion
Exercises
Exercise #1
Exercise #2
Function prologue and epilogue
Recursion
Stack
Why does the stack grow backwards?
What is the stack used for?
Save the function's return address
Passing function arguments
Local variable storage
x86: alloca() function
(Windows) SEH
Buffer overflow protection
Automatic deallocation of data in stack
A typical stack layout
Noise in stack
Exercises
Exercise #1
Exercise #2
printf() with several arguments
x86
x86: 3 arguments
x64: 8 arguments
ARM
ARM: 3 arguments
ARM: 8 arguments
MIPS
3 arguments
8 arguments
Conclusion
By the way
scanf()
Simple example
About pointers
x86
MSVC + OllyDbg
x64
ARM
MIPS
Global variables
MSVC: x86
MSVC: x86 + OllyDbg
GCC: x86
MSVC: x64
ARM: Optimizing Keil 6/2013 (Thumb mode)
ARM64
MIPS
scanf() result checking
MSVC: x86
MSVC: x86: IDA
MSVC: x86 + OllyDbg
MSVC: x86 + Hiew
MSVC: x64
ARM
MIPS
Exercise
Exercises
Exercise #1
Accessing passed arguments
x86
MSVC
MSVC + OllyDbg
GCC
x64
MSVC
GCC
GCC: uint64_t instead of int
ARM
Non-optimizing Keil 6/2013 (ARM mode)
Optimizing Keil 6/2013 (ARM mode)
Optimizing Keil 6/2013 (Thumb mode)
ARM64
MIPS
More about results returning
Attempt to use the result of a function returning void
What if we do not use the function result?
Returning a structure
Pointers
Global variables example
Local variables example
Conclusion
GOTO operator
Dead code
Exercise
Conditional jumps
Simple example
x86
ARM
MIPS
Calculating absolute value
Optimizing MSVC
Optimizing Keil 6/2013: Thumb mode
Optimizing Keil 6/2013: ARM mode
Non-optimizing GCC 4.9 (ARM64)
MIPS
Branchless version?
Ternary conditional operator
x86
ARM
ARM64
MIPS
Let's rewrite it in an if/else way
Conclusion
Getting minimal and maximal values
32-bit
64-bit
MIPS
Conclusion
x86
ARM
MIPS
Branchless
Exercise
switch()/case/default
Small number of cases
x86
ARM: Optimizing Keil 6/2013 (ARM mode)
ARM: Optimizing Keil 6/2013 (Thumb mode)
ARM64: Non-optimizing GCC (Linaro) 4.9
ARM64: Optimizing GCC (Linaro) 4.9
MIPS
Conclusion
A lot of cases
x86
ARM: Optimizing Keil 6/2013 (ARM mode)
ARM: Optimizing Keil 6/2013 (Thumb mode)
MIPS
Conclusion
When there are several case statements in one block
MSVC
GCC
ARM64: Optimizing GCC 4.9.1
Fall-through
MSVC x86
ARM64
Exercises
Exercise #1
Loops
Simple example
x86
x86: OllyDbg
x86: tracer
ARM
MIPS
One more thing
Memory blocks copying routine
Straight-forward implementation
ARM in ARM mode
MIPS
Vectorization
Conclusion
Exercises
Exercise #1
Exercise #2
Exercise #3
Exercise #4
Simple C-strings processing
strlen()
x86
ARM
MIPS
Exercises
Exercise #1
Replacing arithmetic instructions to other ones
Multiplication
Multiplication using addition
Multiplication using shifting
Multiplication using shifting, subtracting, and adding
Division
Division using shifts
Exercises
Exercise #2
Floating-point unit
IEEE 754
x86
ARM, MIPS, x86/x64 SIMD
C/C++
Simple example
x86
ARM: Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
ARM: Optimizing Keil 6/2013 (Thumb mode)
ARM64: Optimizing GCC (Linaro) 4.9
ARM64: Non-optimizing GCC (Linaro) 4.9
MIPS
Passing floating point numbers via arguments
x86
ARM + Non-optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
ARM + Non-optimizing Keil 6/2013 (ARM mode)
ARM64 + Optimizing GCC (Linaro) 4.9
MIPS
Comparison example
x86
ARM
ARM64
MIPS
Stack, calculators and reverse Polish notation
x64
Exercises
Exercise #1
Exercise #2
Arrays
Simple example
x86
ARM
MIPS
Buffer overflow
Reading outside array bounds
Writing beyond array bounds
Buffer overflow protection methods
Optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
One more word about arrays
Array of pointers to strings
x64
32-bit ARM
ARM64
MIPS
Array overflow
Multidimensional arrays
Two-dimensional array example
Access two-dimensional array as one-dimensional
Three-dimensional array example
More examples
Pack of strings as a two-dimensional array
32-bit ARM
ARM64
MIPS
Conclusion
Conclusion
Exercises
Exercise #1
Exercise #2
Exercise #3
Exercise #4
Exercise #5
Manipulating specific bit(s)
Specific bit checking
x86
ARM
Setting and clearing specific bits
x86
ARM + Optimizing Keil 6/2013 (ARM mode)
ARM + Optimizing Keil 6/2013 (Thumb mode)
ARM + Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
ARM: more about the BIC instruction
ARM64: Optimizing GCC (Linaro) 4.9
ARM64: Non-optimizing GCC (Linaro) 4.9
MIPS
Shifts
Setting and clearing specific bits: FPU example
A word about the XOR operation
x86
MIPS
ARM
Counting bits set to 1
x86
x64
ARM + Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
ARM + Optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
ARM64 + Optimizing GCC 4.9
ARM64 + Non-optimizing GCC 4.9
MIPS
Conclusion
Check for specific bit (known at compile stage)
Check for specific bit (specified at runtime)
Set specific bit (known at compile stage)
Set specific bit (specified at runtime)
Clear specific bit (known at compile stage)
Clear specific bit (specified at runtime)
Exercises
Exercise #1
Exercise #2
Exercise #3
Exercise #4
Linear congruential generator
x86
x64
32-bit ARM
MIPS
MIPS relocations
Thread-safe version of the example
Structures
MSVC: SYSTEMTIME example
OllyDbg
Replacing the structure with array
Let's allocate space for a structure using malloc()
UNIX: struct tm
Linux
ARM
MIPS
Structure as a set of values
Structure as an array of 32-bit words
Structure as an array of bytes
Fields packing in structure
x86
ARM
MIPS
One more word
Nested structures
OllyDbg
Bit fields in a structure
CPUID example
Working with the float type as with a structure
Exercises
Exercise #1
Exercise #2
Unions
Pseudo-random number generator example
x86
MIPS
ARM (ARM mode)
Calculating machine epsilon
x86
ARM64
MIPS
Conclusion
Fast square root calculation
Pointers to functions
MSVC
MSVC + OllyDbg
MSVC + tracer
MSVC + tracer (code coverage)
GCC
GCC + GDB (with source code)
GCC + GDB (no source code)
64-bit values in 32-bit environment
Returning of 64-bit value
x86
ARM
MIPS
Arguments passing, addition, subtraction
x86
ARM
MIPS
Multiplication, division
x86
ARM
MIPS
Shifting right
x86
ARM
MIPS
Converting 32-bit value into 64-bit one
x86
ARM
MIPS
SIMD
Vectorization
Addition example
Memory copy example
SIMD strlen() implementation
64 bits
x86-64
ARM
Float point numbers
Working with floating point numbers using SIMD
Simple example
x64
x86
Passing floating point number via arguments
Comparison example
x64
x86
Calculating machine epsilon: x64 and SIMD
Pseudo-random number generator example revisited
Summary
ARM-specific details
Number sign (#) before number
Addressing modes
Loading a constant into a register
32-bit ARM
ARM64
Relocs in ARM64
MIPS-specific details
Loading constants into register
Further reading about MIPS
II Important fundamentals
Signed number representations
Endianness
Big-endian
Little-endian
Example
Bi-endian
Converting data
Memory
CPU
Branch predictors
Data dependencies
Hash functions
How one-way function works?
III Slightly more advanced examples
Temperature converting
Integer values
Optimizing MSVC 2012 x86
Optimizing MSVC 2012 x64
Floating-point values
Fibonacci numbers
Example #1
Example #2
Summary
CRC32 calculation example
Network address calculation example
calc_network_address()
form_IP()
print_as_IP()
form_netmask() and set_bit()
Summary
Loops: several iterators
Three iterators
Two iterators
Intel C++ 2011 case
Duff's device
Division by 9
x86
ARM
Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
Optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
Non-optimizing Xcode 4.6.3 (LLVM) and Keil 6/2013
MIPS
How it works
More theory
Getting the divisor
Variant #1
Variant #2
Exercise #1
String to number conversion (atoi())
Simple example
Optimizing MSVC 2013 x64
Optimizing GCC 4.9.1 x64
Optimizing Keil 6/2013 (ARM mode)
Optimizing Keil 6/2013 (Thumb mode)
Optimizing GCC 4.9.1 ARM64
A slightly advanced example
Optimizing GCC 4.9.1 x64
Optimizing Keil 6/2013 (ARM mode)
Exercise
Inline functions
Strings and memory functions
strcmp()
strlen()
strcpy()
memset()
memcpy()
memcmp()
IDA script
C99 restrict
Branchless abs() function
Optimizing GCC 4.9.1 x64
Optimizing GCC 4.9 ARM64
Variadic functions
Computing arithmetic mean
cdecl calling conventions
Register-based calling conventions
vprintf() function case
Strings trimming
x64: Optimizing MSVC 2013
x64: Non-optimizing GCC 4.9.1
x64: Optimizing GCC 4.9.1
ARM64: Non-optimizing GCC (Linaro) 4.9
ARM64: Optimizing GCC (Linaro) 4.9
ARM: Optimizing Keil 6/2013 (ARM mode)
ARM: Optimizing Keil 6/2013 (Thumb mode)
MIPS
toupper() function
x64
Two comparison operations
One comparison operation
ARM
GCC for ARM64
Summary
Incorrectly disassembled code
Disassembling from an incorrect start (x86)
How does random noise looks disassembled?
Obfuscation
Text strings
Executable code
Inserting garbage
Replacing instructions with bloated equivalents
Always executed/never executed code
Making a lot of mess
Using indirect pointers
Virtual machine / pseudo-code
Other things to mention
Exercises
Exercise #1
C++
Classes
A simple example
Class inheritance
Encapsulation
Multiple inheritance
Virtual methods
ostream
References
STL
std::string
std::list
std::vector
std::map and std::set
Negative array indices
Windows 16-bit
Example#1
Example #2
Example #3
Example #4
Example #5
Example #6
Global variables
IV Java
Java
Introduction
Returning a value
Simple calculating functions
JVM memory model
Simple function calling
Calling beep()
Linear congruential PRNG
Conditional jumps
Passing arguments
Bitfields
Loops
switch()
Arrays
Simple example
Summing elements of array
main() function sole argument is array too
Pre-initialized array of strings
Variadic functions
Two-dimensional arrays
Three-dimensional arrays
Summary
Strings
First example
Second example
Exceptions
Classes
Simple patching
First example
Second example
Summary
V Finding important/interesting stuff in the code
Identification of executable files
Microsoft Visual C++
Name mangling
GCC
Name mangling
Cygwin
MinGW
Intel FORTRAN
Watcom, OpenWatcom
Name mangling
Borland
Delphi
Other known DLLs
Communication with the outer world (win32)
Often used functions in the Windows API
tracer: Intercepting all functions in specific module
Strings
Text strings
C/C++
Borland Delphi
Unicode
Base64
Error/debug messages
Suspicious magic strings
Calls to assert()
Constants
Magic numbers
DHCP
Searching for constants
Finding the right instructions
Suspicious code patterns
XOR instructions
Hand-written assembly code
Using magic numbers while tracing
Other things
General idea
C++
Some binary file patterns
Memory "snapshots" comparing
Windows registry
Blink-comparator
VI OS-specific
Arguments passing methods (calling conventions)
cdecl
stdcall
Functions with variable number of arguments
fastcall
GCC regparm
Watcom/OpenWatcom
thiscall
x86-64
Windows x64
Linux x64
Return values of float and double type
Modifying arguments
Taking a pointer to function argument
Thread Local Storage
Linear congruential generator revisited
Win32
Linux
System calls (syscall-s)
Linux
Windows
Linux
Position-independent code
Windows
LD_PRELOAD hack in Linux
Windows NT
CRT (win32)
Win32 PE
Terminology
Base address
Subsystem
OS version
Sections
Relocations (relocs)
Exports and imports
Resources
.NET
TLS
Tools
Further reading
Windows SEH
Let's forget about MSVC
Now let's get back to MSVC
Windows x64
Read more about SEH
Windows NT: Critical section
VII Tools
Disassembler
IDA
Debugger
OllyDbg
GDB
tracer
System calls tracing
strace / dtruss
Decompilers
Other tools
VIII Examples of real-world RE tasks
Task manager practical joke (Windows Vista)
Using LEA to load values
Color Lines game practical joke
Minesweeper (Windows XP)
Exercises
Hand decompiling + Z3 SMT solver
Hand decompiling
Now let's use the Z3 SMT solver
Dongles
Example #1: MacOS Classic and PowerPC
Example #2: SCO OpenServer
Decrypting error messages
Example #3: MS-DOS
"QR9": Rubik's cube inspired amateur crypto-algorithm
SAP
About SAP client network traffic compression
SAP 6.0 password checking functions
Oracle RDBMS
V$VERSION table in the Oracle RDBMS
X$KSMLRU table in Oracle RDBMS
V$TIMER table in Oracle RDBMS
Handwritten assembly code
EICAR test file
Demos
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
Trixter's 42 byte version
My attempt to reduce Trixter's version: 27 bytes
Taking random memory garbage as a source of randomness
Conclusion
Mandelbrot set
Theory
Let's get back to the demo
My "fixed" version
IX Examples of reversing proprietary file formats
Primitive XOR-encryption
Norton Guide: simplest possible 1-byte XOR encryption
Entropy
Simplest possible 4-byte XOR encryption
Exercise
Millenium game save file
Oracle RDBMS: .SYM-files
Oracle RDBMS: .MSB-files
Summary
X Other things
npad
Executable files patching
Text strings
x86 code
Compiler intrinsic
Compiler's anomalies
OpenMP
MSVC
GCC
Itanium
8086 memory model
Basic blocks reordering
Profile-guided optimization
XI Books/blogs worth reading
Books
Windows
C/C++
x86 / x86-64
ARM
Cryptography
Blogs
Windows
Other
XII Exercises
Level 1
Exercise 1.4
Level 2
Exercise 2.1
Optimizing MSVC 2010 x86
Optimizing MSVC 2012 x64
Exercise 2.4
Optimizing MSVC 2010
GCC 4.4.1
Optimizing Keil (ARM mode)
Optimizing Keil (Thumb mode)
Optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.4.5 (MIPS)
Exercise 2.6
Optimizing MSVC 2010
Optimizing Keil (ARM mode)
Optimizing Keil (Thumb mode)
Optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.4.5 (MIPS)
Exercise 2.13
Optimizing MSVC 2012
Keil (ARM mode)
Keil (Thumb mode)
Optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.4.5 (MIPS)
Exercise 2.14
MSVC 2012
Keil (ARM mode)
GCC 4.6.3 for Raspberry Pi (ARM mode)
Optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.4.5 (MIPS)
Exercise 2.15
Optimizing MSVC 2012 x64
Optimizing GCC 4.4.6 x64
Optimizing GCC 4.8.1 x86
Keil (ARM mode): Cortex-R4F CPU as target
Optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.4.5 (MIPS)
Exercise 2.16
Optimizing MSVC 2012 x64
Optimizing Keil (ARM mode)
Optimizing Keil (Thumb mode)
Non-optimizing GCC 4.9.1 (ARM64)
Optimizing GCC 4.9.1 (ARM64)
Non-optimizing GCC 4.4.5 (MIPS)
Exercise 2.17
Exercise 2.18
Exercise 2.19
Exercise 2.20
Level 3
Exercise 3.2
Exercise 3.3
Exercise 3.4
Exercise 3.5
Exercise 3.6
Exercise 3.8
crackme / keygenme
Afterword
Questions?
Appendix
x86
Terminology
General purpose registers
RAX/EAX/AX/AL
RBX/EBX/BX/BL
RCX/ECX/CX/CL
RDX/EDX/DX/DL
RSI/ESI/SI/SIL
RDI/EDI/DI/DIL
R8/R8D/R8W/R8L
R9/R9D/R9W/R9L
R10/R10D/R10W/R10L
R11/R11D/R11W/R11L
R12/R12D/R12W/R12L
R13/R13D/R13W/R13L
R14/R14D/R14W/R14L
R15/R15D/R15W/R15L
RSP/ESP/SP/SPL
RBP/EBP/BP/BPL
RIP/EIP/IP
CS/DS/ES/SS/FS/GS
Flags register
FPU registers
Control Word
Status Word
Tag Word
SIMD registers
MMX registers
SSE and AVX registers
Debugging registers
DR6
DR7
Instructions
Prefixes
Most frequently used instructions
Less frequently used instructions
FPU instructions
Instructions having printable ASCII opcode
ARM
Terminology
Versions
32-bit ARM (AArch32)
General purpose registers
Current Program Status Register (CPSR)
VFP (floating point) and NEON registers
64-bit ARM (AArch64)
General purpose registers
Instructions
Conditional codes table
MIPS
Registers
General purpose registers GPR
Floating-point registers
Instructions
Jump instructions
Some GCC library functions
Some MSVC library functions
Cheatsheets
IDA
OllyDbg
MSVC
GCC
GDB
Exercise solutions
Per chapter
"Hello, world!" chapter
"Stack" chapter
"scanf()" chapter
"switch()/case/default" chapter
Exercise #1
"Loops" chapter
Exercise #3
Exercise #4
"Simple C-strings processing" chapter
Replacing arithmetic instructions to other ones *'c'hapter
"Floating-point unit" chapter
"Arrays" chapter
"Manipulating specific bit(s)" chapter
"Structures" chapter
"Obfuscation" chapter
"Division by 9" chapter
Level 1
Exercise 1.1
Exercise 1.4
Level 2
Exercise 2.1
Exercise 2.4
Exercise 2.6
Exercise 2.13
Exercise 2.14
Exercise 2.15
Exercise 2.16
Exercise 2.17
Exercise 2.18
Exercise 2.19
Exercise 2.20
Level 3
Exercise 3.2
Exercise 3.3
Exercise 3.4
Exercise 3.5
Exercise 3.6
Exercise 3.8
Other
"Minesweeper (Windows XP)" example
Acronyms used
Glossary
Index
Bibliography
The book hasn't received reviews yet.