Getting Started
August 8th, 2025
Overview
The initial start for this section will discuss necessary Assembly functions. The actual reversing of malware will be conducted in the next section. I would also like to clarify that I am by no means an expert, and that this is a learning experience to me as much as it is for you!
Assembly Functions
General Purpose Registers
This can be thought of as the foundation for tasks and operations. They are held in the CPU's super-fast storage locations. When you want to compute an arithmetic operation, do a simple for loop, or grow gray hairs, the GPRs are in play.

Segments
As such, with every programming language, there must be a way to perform actions. The GP instructions perform basic movement, arithmetic, logic, program flow, and string operations that are used to write application and system software. Although we won't mention every data instruction, we will cover the important ones for Assembly programming.
Moving data between the memory and other regions of the CPU can be thought of as this:
When looking at a process, there is one task that must happen: segmentation. Think of your process as a pie; what segmentation does is cut that pie into varying sizes depending on a person's desired slice.
This is the same case for Segmentation, the segment registers are constantly used for numerous important tasks, from moving memory and data to fetching instructions. Each segment that they point to can be a different size, similar to how your friends may have different sizes for their pie.

Registers
Assembly uses Registers which are small and fast storage components within a CPU, they can be used for performing multiple tasks while maintaining efficiency. The types of registers include; General-Purpose Registers, Flag Registers, Segment Registers, Pointer Registers and Index Registers.
Registers can be paired with other instructions such as mov, add, or cmp. The leading "E" indicates that it is a 32-bit register, meanwhile, a leading "R" would indicate a 64-bit register
General-Purpose Registers
General-Purpose Registers can be used to storage data, addresses or calculate.
EAX
Accumulator Register used for arithmetic purpose
EBX
Base Register used for addressing
ECX
Count Register used for loop operations
EDX
Data Register used in conjunction with EAX for certain operations
Registers also consist of their lower and higher bit counter parts. 32-bit registers use the "E" letter for extended registers, while 64-bit registers use the "R" letter for a full Register. These both stem from the 16-bit register which does not have a leading letter, consisting of AX, BX, CX, and DX . Lastly, there are 8-bit registers which are taken from the lower and higher half of a 16-bit register.
RAX
AX
AH, AL
RBX
BX
BH, BL
RCX
CX
CH, CL
RDX
DX
DH, DL

Index Registers
Index Registers consist of their 32 and 16-bit counterparts, which aid in addition and subtraction (sometimes), but are mainly used for indexed addressing.
RSI (64-bit) ESI (32-bit) SI (16-bit)
source index for string operations
RDI (64-bit) EDI (32-bit) Di (16-bit)
destination index for string operations
In terms of string operations, these are not to be confused with generic strings (such as print statements). These registers input and output from a buffer index and are generally used with the following functions:
MOVSB- Move a byte fromESItoEDIMOVSW- Move a word (16-bit)MOVSD- Move a double word (32-bit)MOVSQ- Move a quad word (64-bit)STOS- Store fromAL/AX/EAX/RAXtoEDI/RDILDOS- Load fromEDI/RDItoAL/AX/EAX/RAX
An example of this would be the code listed below, the char buffer[400] allows a maximum of 400 bytes, which is correctly matched with the reading process of (0, buffer, 400); anything past this would result in a buffer overflow. The buffer pointer would be the EDI, as it will be used to point to the destination; an ESI is nowhere to be found due to stdin.
Pointer Registers
Pointer Registers are designed to hold a memory address from another location, handle function calls, point to data in memory, and assist in memory operations. They are commonly used to control micro-controllers by accessing the memory-mapped peripheral registers. Similar to all other registers, they consist of 64, 32, and 16-bit versions, respectively.
Instruction Pointer
RIP(64) EIP(32) IP(16)
stores the offset address of the next instruction to be executed
Stack Pointer
RSP(64) ESP(32) SP(16)
provides the offset value within the program stack
Base Pointer
RBP(64) EBP(32) BP(16)
helps in referencing the parameter variables passed to a subroutine
Data Movement
X86 Assembly has an immense amount of data transfer instructions; someone like you and me may just lose their heads trying to understand everything. However, fret not, for we will only be covering the necessary Assembly instructions in accordance with our Malware Analysis, learning more is always a good thing, but for our sake, keeping our sanity is the first of our problems!
mov - move data from GPRs, move data between memory and GP/Segment Registers, or move immediately to GPRs
push - push onto a stack
pop - pop (remove) off the stack
xchg - exchange
bswap - byte swap
dst - destination (where a value is stored or written)
src - source (data being read or manipulated)
add - integer add
sub - subtract
inc - increment
dec - decrement
mul - unsigned multiply
div - unsigned divide
neg - negate
and - perform bitwise logical AND
or - perform bitwise logical OR
xor - perform bitwise logical XOR
not - perform bitwise logical NOT
shl - shift logical left
shr - shift logical right
test - logical compare
je - jump if equal
jne - jump if not equal
jg - jump if greater
jl - jump if less
jz - jump if zero
jnz - jump if NOT zero
jmp - jump
jmp - jump
call - call procedure
ret - return
loop - loop with ECX counter (count register for loops)
jecxz - jump register ECX zero
Debugging Example
The C program above opens a handle from a specific PID, which then prints out the handle to the process using the OpenProcess Function.

Looking at the information provided by x64DBG, we can see the OpenHandle program
References
Last updated

