Tidy up
This commit is contained in:
103 files changed
+3663
-3779
No files matched your search
@@ -1,13 +1,13 @@
|
||||
# Crash Course in x86 Assembler
|
||||
|
||||
- Malware authors creates programs at the high-level language and use a compiler to generate machine code to by run by the CPU
|
||||
- Malware analysts operate at the low-level language. Using disassembler to generate assembly code from the machine code to try and understand how the malware works
|
||||
- Malware authors create programs in a high-level language and use a compiler to generate machine code to be run by the CPU
|
||||
- Malware analysts operate at the low-level language, using a disassembler to generate assembly code from the machine code to try and understand how the malware works
|
||||
|
||||

|
||||
|
||||
### x86 Architecture
|
||||
|
||||
x86 architecture follows the Von Neuman architecture and has three hardware components
|
||||
x86 architecture follows the von Neumann architecture and has three hardware components
|
||||
|
||||
- CPU executes code
|
||||
- Main memory (RAM) stores all data and code instructions
|
||||
@@ -23,7 +23,7 @@ The main memory for a single program can be divided into the following four majo
|
||||
|
||||
**Data** - Contains values that are put in place when a program is initially loaded
|
||||
|
||||
**Code** - Includes the instructions fetched by the CPU to execute the programs tasks. The code controls what the program does
|
||||
**Code** - Includes the instructions fetched by the CPU to execute the program’s tasks. The code controls what the program does
|
||||
|
||||
**Heap** - The heap is used for dynamic memory during program execution, to create (or allocate) new values and eliminate (free) values that the program no longer needs. The heap’s size changes frequently while the program runs
|
||||
|
||||
@@ -37,11 +37,11 @@ Each instruction is comprised of an **opcode** and zero or more **operands**.
|
||||
|
||||
**operand** - argument or data
|
||||
|
||||
**endianess**
|
||||
**endianness**
|
||||
|
||||
- Whether the most significant bit is at the start or the end of a binary stream.
|
||||
- **Big-endian** is where the most significant bit is first
|
||||
- **Little-endian** is where the least significant bit is first
|
||||
- **Big-endian** is where the most significant bit is first
|
||||
- **Little-endian** is where the least significant bit is first
|
||||
|
||||
Disassemblers translate opcodes into human-readable instructions e.g.
|
||||
|
||||
@@ -69,13 +69,13 @@ A register is a small amount of data storage available to the CPU, that’s real
|
||||
|
||||

|
||||
|
||||
All general registers are 32-bits but can be referenced as either 32 or 16 bits in assembly code (for backwards compatibility reasons)
|
||||
All general registers are 32 bits but can be referenced as either 32 or 16 bits in assembly code (for backwards compatibility reasons)
|
||||
|
||||
`EDX` - full 32-bits
|
||||
`EDX` - full 32 bits
|
||||
|
||||
`DX` - lower 16 bits
|
||||
|
||||
Registers `EAX`, `EBX`, `ECX`, `EDX` can be referenced as 8 bit registers
|
||||
Registers `EAX`, `EBX`, `ECX`, `EDX` can be referenced as 8-bit registers
|
||||
|
||||

|
||||
|
||||
@@ -87,7 +87,7 @@ Some x86 instructions use specific registers by definition.
|
||||
|
||||
###### Flags
|
||||
|
||||
The `EFLAGS` register is a status register 32-bits big, this means it can store 32 flags. During execution, each flag is either set to 1 if true
|
||||
The `EFLAGS` register is a status register 32 bits big; this means it can store 32 flags. During execution, each flag is set to 1 if true
|
||||
|
||||
- **ZF** - The zero flag is set if the result of the operation was equal to zero
|
||||
- **CF** - The carry flag is set when the result of an operation is too large or too small for the destination operand.
|
||||
@@ -102,7 +102,7 @@ The `EFLAGS` register is a status register 32-bits big, this means it can store
|
||||
|
||||
`nop` - no operation - does nothing
|
||||
|
||||
When issued, execution simply preceeds to the next instruction
|
||||
When issued, execution simply proceeds to the next instruction
|
||||
|
||||
#### The Stack
|
||||
|
||||
@@ -118,17 +118,17 @@ Main code calls and temporarily transfers execution to functions before returnin
|
||||
|
||||
Many functions contain a **prologue** and an **epilogue**
|
||||
|
||||
- The **prologue** is a few lines of code at the start of the function which prepares the stack and registers for use within the function
|
||||
- The **prologue** is a few lines of code at the start of the function which prepare the stack and registers for use within the function
|
||||
- The **epilogue** is at the end of the function and restores the stack and registers to their state before the function was called
|
||||
|
||||
When a function is called:
|
||||
|
||||
1. Arguments are placed on the stack using `push` instructions
|
||||
2. A function called using `memory_location` which changes `EIP` to the address of the first instruction in the function and returns `EIP` to main code once the function is finished
|
||||
2. A function is called using `memory_location` which changes `EIP` to the address of the first instruction in the function and returns `EIP` to main code once the function is finished
|
||||
3. The function prologue pushes local variables, parameters and `EBP` onto the stack
|
||||
4. The function executes
|
||||
5. The function epilogue restores the stack, `ESP` is adjusted to free local variables, and `EBP` is restored so that the calling function can address its variables.
|
||||
- The `leave` instruction sets `ESP` equal to `EBP` and pops `EBP` off the stack
|
||||
- The `leave` instruction sets `ESP` equal to `EBP` and pops `EBP` off the stack
|
||||
6. The function returns by calling `ret`, this pops the return address off the stack into `EIP`
|
||||
7. The stack is adjusted to remove sent arguments
|
||||
|
||||
@@ -138,7 +138,7 @@ When a function is called:
|
||||
|
||||
###### Passing Arguments
|
||||
|
||||
`c` functions and windows `api` calls, functions are called differently.
|
||||
`c` functions and Windows `api` calls use different calling conventions.
|
||||
|
||||
There are two things to think about
|
||||
|
||||
@@ -164,14 +164,16 @@ ret = test (a, b, c);
|
||||
|
||||
- Return value stored in `EAX`
|
||||
|
||||
- ```assembly
|
||||
push c
|
||||
push b
|
||||
push a
|
||||
call test
|
||||
add esp, 12
|
||||
mov ret, eax
|
||||
```
|
||||
- Example:
|
||||
|
||||
```assembly
|
||||
push c
|
||||
push b
|
||||
push a
|
||||
call test
|
||||
add esp, 12
|
||||
mov ret, eax
|
||||
```
|
||||
|
||||
- Note line 5 is the caller cleaning up the stack
|
||||
|
||||
@@ -189,12 +191,11 @@ ret = test (a, b, c);
|
||||
- In `fastcall` the first few arguments (typically first two) are passed in registers `EDX` and `ECX`
|
||||
- Additional arguments are loaded right to left
|
||||
- Calling function is responsible for cleaning the stack
|
||||
- This is quicker as less data needs to be pushed to and retrived from the stack
|
||||
- # Functions have underscore prefix, name followed by `@` and length of arguments
|
||||
- This is quicker as less data needs to be pushed to and retrieved from the stack
|
||||
- Functions have an underscore prefix, name followed by `@` and length of arguments
|
||||
|
||||
When debugging windows functions, you can look at `EBP` to retrace the route the program took through the code
|
||||
When debugging Windows functions, you can look at `EBP` to retrace the route the program took through the code
|
||||
|
||||
#### Conditionals
|
||||
|
||||

|
||||
|
||||
Reference in new issue
Block a user